Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

A pure-C compiler?

133 views
Skip to first unread message

Anton Shepelev

unread,
Aug 27, 2018, 4:21:37 PM8/27/18
to
Following on an on-going discussion, I want to ask
everybody: is there a compiler that can be set up to accept
only standard C, that is the language as defined in one of
the several ISO standards for "The programming language C"?
I believe such a compiler would be extremely useful for
everyone who cares about portability or take interest in
pure C.

--
() ascii ribbon campaign -- against html e-mail
/\ http://preview.tinyurl.com/qcy6mjc [archived]

Keith Thompson

unread,
Aug 27, 2018, 4:36:21 PM8/27/18
to
Anton Shepelev <anto...@gmail.com> writes:
> Following on an on-going discussion, I want to ask
> everybody: is there a compiler that can be set up to accept
> only standard C, that is the language as defined in one of
> the several ISO standards for "The programming language C"?
> I believe such a compiler would be extremely useful for
> everyone who cares about portability or take interest in
> pure C.

The language defined by the ISO C standard explicitly permits extensions
that do not alter the behavior of any strictly conforming program.

I think what you're asking about is a conforming ISO C implementation
that provides no extensions. It could be useful for detecting code that
relies on such extensions. Options to enable and disable optional
features, such as VLAs and complex types, could also be useful.

Another issue is implementation-defined features. For example, this:

unsigned long n = 42;
size_t *ptr = &n;

is not portable, but it's perfectly valid under a conforming
implementation that defines size_t as unsigned long. A compiler that
nevertheless warns about this kind of construct could be useful.

Now that I've expanded on your question, my answer is still that I don't
know whether such a compiler exists.

--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Anton Shepelev

unread,
Aug 27, 2018, 4:50:31 PM8/27/18
to
Keith Thompson to Anton Shepelev:

> > Following on an on-going discussion, I want to ask
> > everybody: is there a compiler that can be set up to
> > accept only standard C, that is the language as defined
> > in one of the several ISO standards for "The programming
> > language C"? I believe such a compiler would be
> > extremely useful for everyone who cares about
> > portability or take interest in pure C.
>
> The language defined by the ISO C standard explicitly
> permits extensions that do not alter the behavior of any
> strictly conforming program.
>
> I think what you're asking about is a conforming ISO C
> implementation that provides no extensions.

Yes.

> It could be useful for detecting code that relies on such
> extensions.

Could not real work be made with it?

> Options to enable and disable optional features, such as
> VLAs and complex types, could also be useful.

Agreed.

> Another issue is implementation-defined features. For
> example, this:
>
> unsigned long n = 42;
> size_t *ptr = &n;
>
> is not portable, but it's perfectly valid under a
> conforming implementation that defines size_t as unsigned
> long. A compiler that nevertheless warns about this kind
> of construct could be useful.

It should be an error by default and a warning if you ask
it.

> Now that I've expanded on your question, my answer is
> still that I don't know whether such a compiler exists.

Which is strage, as if nobody cared about portability,
especially because implementing such restrictios in an
existing compiler seems orders of magnitude simpler than
implementing the compiler itself. The easiest interface
would be a single --pure switch.

Ben Bacarisse

unread,
Aug 27, 2018, 5:06:48 PM8/27/18
to
Anton Shepelev <anto...@gmail.com> writes:
<snip>
>> Now that I've expanded on your question, my answer is
>> still that I don't know whether such a compiler exists.
>
> Which is strage, as if nobody cared about portability,
> especially because implementing such restrictios in an
> existing compiler seems orders of magnitude simpler than
> implementing the compiler itself. The easiest interface
> would be a single --pure switch.

And of course there's no need for it to be a compiler! That's why there
used to be 'lint' (and I am sure it and derivatives exist).

I wonder if that sort of tool can get close to doing what you want?

--
Ben.

Anton Shepelev

unread,
Aug 27, 2018, 5:08:17 PM8/27/18
to
Stefan Ram to Anton Shepelev:

> > is there a compiler that can be set up to accept only
> > standard C, that is the language as defined in one of
> > the several ISO standards for "The programming language
> > C"?
>
> There is only one such ISO standard. The others are
> "canceled and replaced".

Supporting older standards may be usefult becuase of legacy
code, technological intertia and backwards compatibility.

> What's wrong with
> gcc -std=c11 -pedantic -pedantic-errors

As has been written elsewhere in the group, it does help:

<pm0pra$e54$1...@dont-email.me>
<pm0tmo$r6a$1...@dont-email.me>

Anton Shepelev

unread,
Aug 27, 2018, 5:16:04 PM8/27/18
to
Ben Bacarisse to Anton Shepelev:

> > Which is strage, as if nobody cared about portability,
> > especially because implementing such restrictios in an
> > existing compiler seems orders of magnitude simpler than
> > implementing the compiler itself. The easiest interface
> > would be a single --pure switch.
>
> And of course there's no need for it to be a compiler!
> That's why there used to be 'lint' (and I am sure it and
> derivatives exist).

A separate tool is better than nothing, but the overlap is
so high and the convenience of having the functionality in
the compiler so tempting that I really should prefer a
literate compiler to a tandem of a dumb compiler and a code
analyser.

I already use three tools in the writing even of simple
programs: Vim, GCC, and make. Adding a fouth tool and
teaching Vim to parse its output is another hassle.

Keith Thompson

unread,
Aug 27, 2018, 5:24:12 PM8/27/18
to
Anton Shepelev <anto...@gmail.com> writes:
> Keith Thompson to Anton Shepelev:
[...]
>> It could be useful for detecting code that relies on such
>> extensions.
>
> Could not real work be made with it?

Sure.

>> Options to enable and disable optional features, such as
>> VLAs and complex types, could also be useful.
>
> Agreed.
>
>> Another issue is implementation-defined features. For
>> example, this:
>>
>> unsigned long n = 42;
>> size_t *ptr = &n;
>>
>> is not portable, but it's perfectly valid under a
>> conforming implementation that defines size_t as unsigned
>> long. A compiler that nevertheless warns about this kind
>> of construct could be useful.
>
> It should be an error by default and a warning if you ask
> it.

An implementation that defines size_t as unsigned long and rejects the
above code would be non-conforming. (Non-conforming implementations can
still be useful, of course.)

A possible solution for this particular case would be to define size_t
as a typedef for some implementation-defined extended integer type.
Then it would be distinct from all the standard unsigned integer types.

There are likely other cases that don't have such easy solutions.

[...]

luser droog

unread,
Aug 28, 2018, 1:16:24 AM8/28/18
to
I used 'splint' recently, right up to the day that it couldn't
handle my variadic x-macros. Then I stopped using it.

It seems it chokes on some (seeming to me) valid C99 constructs.
Does anyone have more recent (or positive) experience?

I really liked it until I couldn' get it to work anymore.

Anton Shepelev

unread,
Aug 28, 2018, 5:36:16 AM8/28/18
to
Keith Thompson to Anton Shepelev:

>>Keith Thompson:
>>
>>>Another issue is implementation-defined features. For
>>>example, this:
>>> unsigned long n = 42;
>>> size_t *ptr = &n;
>>>
>>>is not portable, but it's perfectly valid under a
>>>conforming implementation that defines size_t as unsigned
>>>long. A compiler that nevertheless warns about this kind
>>>of construct could be useful.
>>
>>It should be an error by default and a warning if you ask
>>it.
>
>An implementation that defines size_t as unsigned long and
>rejects the above code would be non-conforming.

Yet the pure-C compiler of my dreams must reject this code
because it cannot guarrantee its portability. When,
however, the programmer indulges in void* machinations, it
shall not interfere, for explicit "loopholes" imply
deliberation.

>A possible solution for this particular case would be to
>define size_t as a typedef for some implementation-defined
>extended integer type. Then it would be distinct from all
>the standard unsigned integer types.

Is this possible on any hardware? I should prefer a device-
independent solution.

--
() ascii ribbon campaign - against html e-mail
/\ http://preview.tinyurl.com/qcy6mjc [archived]

Anton Shepelev

unread,
Aug 28, 2018, 5:39:22 AM8/28/18
to
Stefan Ram:

>C makes no requirements about the number of subroutines
>that can be called simultaneously (about the "stack size"),
>so even when a program is fully portable, we do not know
>whether all implementations will execute even a single
>function call. Insofar, even writing a strictly conforming
>programs does not guarantee that it really can be executed
>under all conforming implementations.

That can't be determined by analysis of code alone and
therefore should not be required of a pure-C compiler.

--
() ascii ribbon campaign - against html e-mail
/\ http://preview.tinyurl.com/qcy6mjc [archived]

James Kuyper

unread,
Aug 28, 2018, 7:38:29 AM8/28/18
to
On 08/28/2018 05:36 AM, Anton Shepelev wrote:
> Keith Thompson to Anton Shepelev:
...
>> A possible solution for this particular case would be to
>> define size_t as a typedef for some implementation-defined
>> extended integer type. Then it would be distinct from all
>> the standard unsigned integer types.
>
> Is this possible on any hardware? I should prefer a device-
> independent solution.

Yes, it could be done on any hardware. It would require emulation of at
least one type on hardware which supports an insufficiently large number
of integer types that are big enough, but that's equally true of long long.

Richard Damon

unread,
Aug 28, 2018, 7:53:40 AM8/28/18
to
No special emulation needed. Just because two types have the same size
and characteristics doesn't mean they need to be the 'same type' (or
even compatible types'

char normally looks just like one of signed char or unsigned char, but
is a distinct type, and pointers to char don't implicitly convert to
either of them.

Traditionally, the type sequence char, short, int, long, long long has
at least one pair of types that look like each other(for the standard 8
bit byte machine, unless long long is 128 bits long it almost has to).
Again, pointer to these same sized types won't be compatible.

I believe any implementation can define a new implementation-defined
type for size_t, and make it have all the characteristics of unsigned
long, but be a distinct type.


Keith Thompson

unread,
Aug 28, 2018, 12:34:10 PM8/28/18
to
Richard Damon <Ric...@Damon-Family.org> writes:
> On 8/28/18 5:36 AM, Anton Shepelev wrote:
>> Keith Thompson to Anton Shepelev:
[...]
>>> A possible solution for this particular case would be to
>>> define size_t as a typedef for some implementation-defined
>>> extended integer type. Then it would be distinct from all
>>> the standard unsigned integer types.
>>
>> Is this possible on any hardware? I should prefer a device-
>> independent solution.
>
> No special emulation needed. Just because two types have the same size
> and characteristics doesn't mean they need to be the 'same type' (or
> even compatible types'

Exactly.

For example, let's say size_t needs to be 64 bits. An implementation
could define an *extended unsigned integer type* (6.2.5p6) called, say,
__size_t (where the name is a compiler-defined keyword), and the
standard headers that define size_t could have:

typedef __size_t size_t;

__size_t would then be distinct from and incompatible with unsigned int,
unsigned long, and unsigned long long, and any attempt to convert a
size_t* value to unsigned long* would trigger a diagnostic. __size_t
could have exactly the same representation as, say, unsigned long.

BGB

unread,
Aug 29, 2018, 2:51:02 PM8/29/18
to
On 8/28/2018 4:39 AM, Anton Shepelev wrote:
> Stefan Ram:
>
>> C makes no requirements about the number of subroutines
>> that can be called simultaneously (about the "stack size"),
>> so even when a program is fully portable, we do not know
>> whether all implementations will execute even a single
>> function call. Insofar, even writing a strictly conforming
>> programs does not guarantee that it really can be executed
>> under all conforming implementations.
>
> That can't be determined by analysis of code alone and
> therefore should not be required of a pure-C compiler.
>

(Encounters this thread randomly): I have a possible example of
something like this.


In some experimental ISAs of mine, with my own C compiler, which during
part (or all) of their operation, use a memory map like this (low 16
bits, high bits are zeroes):
0000..7FFF: ROM
8000..BFFF: Reserved
C000..DFFF: SRAM
E000..FFFF: Reserved

Within the RAM area, the area near C000 is the ".data" and ".bss"
sections, in the middle is the heap (sorta), and starting at DFF0 (and
working downwards) is the stack.

It probably doesn't take much of a guess to realize that large memory
allocations or deep recursion are basically out of the question with 8kB
of RAM.

There is a 32-bit ISA for which things generally live entirely in this
address space, and a 64-bit ISA which only uses this memory map during boot.


Granted, 8kB of RAM is pretty huge vs the 0.5kB to 2kB typical on most
8/16 bit microcontrollers, but, it is a similar sort of idea with these
as well.

Tim Rentsch

unread,
Sep 24, 2018, 9:24:30 AM9/24/18
to
Keith Thompson <ks...@mib.org> writes:

> Anton Shepelev <anto...@gmail.com> writes:
>
>> Keith Thompson to Anton Shepelev:
>
> [...]
>
>>> Another issue is implementation-defined features. For
>>> example, this:
>>>
>>> unsigned long n = 42;
>>> size_t *ptr = &n;
>>>
>>> is not portable, but it's perfectly valid under a
>>> conforming implementation that defines size_t as unsigned
>>> long. A compiler that nevertheless warns about this kind
>>> of construct could be useful.
>>
>> It should be an error by default and a warning if you ask
>> it.
>
> An implementation that defines size_t as unsigned long and rejects
> the above code would be non-conforming.

The Standard requires conforming implementations to accept
strictly conforming programs. The Standard does not require that
any other programs be accepted. A conforming implementation is
free not to accept a program with the above code it, regardless
of whether size_t is the same type as unsigned long.
0 new messages