Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #104069 > unrolled thread

Standard Headers

Started byBartC <bc@freeuk.com>
First post2017-02-17 16:34 +0000
Last post2017-02-19 16:00 -0800
Articles 20 on this page of 24 — 12 participants

Back to article view | Back to comp.lang.c


Contents

  Standard Headers BartC <bc@freeuk.com> - 2017-02-17 16:34 +0000
    Re: Standard Headers supercat@casperkitty.com - 2017-02-17 08:50 -0800
      Re: Standard Headers luser droog <luser.droog@gmail.com> - 2017-02-17 09:08 -0800
        Re: Standard Headers Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-02-17 20:31 +0000
    Re: Standard Headers GOTHIER Nathan <nathan.gothier@gmail.com> - 2017-02-17 18:09 +0100
    Re: Standard Headers "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-02-17 09:18 -0800
    Re: Standard Headers Keith Thompson <kst-u@mib.org> - 2017-02-17 09:26 -0800
      Re: Standard Headers BartC <bc@freeuk.com> - 2017-02-17 17:53 +0000
        Re: Standard Headers me <crisdunbar@gmail.com> - 2017-02-17 10:23 -0800
          Re: Standard Headers BartC <bc@freeuk.com> - 2017-02-17 18:45 +0000
            Re: Standard Headers GOTHIER Nathan <nathan.gothier@gmail.com> - 2017-02-17 19:54 +0100
              Re: Standard Headers Keith Thompson <kst-u@mib.org> - 2017-02-17 12:27 -0800
    Re: Standard Headers jameskuyper@verizon.net - 2017-02-17 11:38 -0800
    Re: Standard Headers Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-02-17 20:49 +0000
      Re: Standard Headers supercat@casperkitty.com - 2017-02-17 13:29 -0800
      Re: Standard Headers BartC <bc@freeuk.com> - 2017-02-17 22:13 +0000
      Re: Standard Headers Nick Bowler <nbowler@draconx.ca> - 2017-02-17 22:28 +0000
        Re: Standard Headers Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-02-18 02:48 +0000
          Re: Standard Headers supercat@casperkitty.com - 2017-02-18 10:26 -0800
            Re: Standard Headers bart4858@gmail.com - 2017-02-18 11:08 -0800
              Re: Standard Headers supercat@casperkitty.com - 2017-02-18 11:45 -0800
    Re: Standard Headers Tim Rentsch <txr@alumni.caltech.edu> - 2017-02-19 13:45 -0800
      Re: Standard Headers BartC <bc@freeuk.com> - 2017-02-19 22:39 +0000
        Re: Standard Headers supercat@casperkitty.com - 2017-02-19 16:00 -0800

Page 1 of 2  [1] 2  Next page →


#104069 — Standard Headers

FromBartC <bc@freeuk.com>
Date2017-02-17 16:34 +0000
SubjectStandard Headers
Message-ID<o878ij$840$1@dont-email.me>
Some questions:

What are the implications (for a normal PC, not embedded devices) of 
having everything in the standard headers already known to a compiler?

That is, as if every source file was prefixed with #includes for the 
20-odd standard C headers.

(And apart from the obvious differences, for example a module with a 
missing #include compiles OK here, but won't compile elsewhere.)

There was another question but I can't remember what it was. In that 
case, let's go with this: The C Standard summarises what's expected in 
the standard headers, but typical headers contain all sorts of extra 
junk, even the smaller ones (I think some of them want to half-implement 
the library functions in the headers).

For example ctype.h ought to contain 14 function declarations, but 
actual headers have from 60 to 360 lines.

The question: will a ctype.h with only 14 lines actually work? (It 
appears to.)

(I'm planning to create my own set of headers, and want to keep them 
minimal, and without bristling with #ifdefs to avoid defining the same 
thing twice. I also intend to have the same headers work on both Windows 
and Linux as much as possible.)

-- 
Bartc

[toc] | [next] | [standalone]


#104070

Fromsupercat@casperkitty.com
Date2017-02-17 08:50 -0800
Message-ID<ae484509-68c0-49cb-88de-ed97918b3400@googlegroups.com>
In reply to#104069
On Friday, February 17, 2017 at 10:34:17 AM UTC-6, Bart wrote:
> What are the implications (for a normal PC, not embedded devices) of 
> having everything in the standard headers already known to a compiler?

The biggest issue is that user code is allowed to use for its own purposes
some of the symbols which appear in various headers, provided that it does
not include the headers in question.  Having a compiler predefine symbols
which happen to be used within user code would thus break what should be
conforming C programs.

This could probably be resolved by having the symbol tables used by both the
preprocessor and compiler include a byte with each symbol that indicates
which #include file, if any, it appears in.  If a compiler has a list of
standard headers whose purpose is soley to define various symbols in the
preprocessor and compiler, and e.g. stdio.h is standard header #6, then
when the preprocessor sees #include <stdio.h> all it will need to do is
set headers_enabled[6].  If the compiler then sees a call to printf, the
symbol table will notice that printf is defined in header #6, and since
headers_enabled[6] is set the symbol table should report that definition.

[toc] | [prev] | [next] | [standalone]


#104072

Fromluser droog <luser.droog@gmail.com>
Date2017-02-17 09:08 -0800
Message-ID<74a56ac9-492c-4535-bfa1-2b1d278ab07f@googlegroups.com>
In reply to#104070
On Friday, February 17, 2017 at 10:50:54 AM UTC-6, supe...@casperkitty.com wrote:
> On Friday, February 17, 2017 at 10:34:17 AM UTC-6, Bart wrote:
> > What are the implications (for a normal PC, not embedded devices) of 
> > having everything in the standard headers already known to a compiler?
> 
> The biggest issue is that user code is allowed to use for its own purposes
> some of the symbols which appear in various headers, provided that it does
> not include the headers in question.  Having a compiler predefine symbols
> which happen to be used within user code would thus break what should be
> conforming C programs.
> 
> This could probably be resolved by having the symbol tables used by both the
> preprocessor and compiler include a byte with each symbol that indicates
> which #include file, if any, it appears in.  If a compiler has a list of
> standard headers whose purpose is soley to define various symbols in the
> preprocessor and compiler, and e.g. stdio.h is standard header #6, then
> when the preprocessor sees #include <stdio.h> all it will need to do is
> set headers_enabled[6].  If the compiler then sees a call to printf, the
> symbol table will notice that printf is defined in header #6, and since
> headers_enabled[6] is set the symbol table should report that definition.

Even better: error messages for undefined symbols could suggest which std
header the programmer forgot to include.

Even better: an option to output the list of #includes which would be
needed for the code to use the std symbols. 

  $compile mycode.c --generate-missing-std-includes

Now that would (could) relieve a substantial burden.

[toc] | [prev] | [next] | [standalone]


#104087

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-02-17 20:31 +0000
Message-ID<87mvdkeeyt.fsf@bsb.me.uk>
In reply to#104072
luser droog <luser.droog@gmail.com> writes:
<snip>
> Even better: error messages for undefined symbols could suggest which std
> header the programmer forgot to include.

Like gcc does:

x.c: In function ‘main’:
x.c:3:6: warning: implicit declaration of function ‘printf’
      printf("%d\n", 42);
      ^
x.c:3:6: warning: incompatible implicit declaration of built-in function ‘printf’
x.c:3:6: note: include ‘<stdio.h>’ or provide a declaration of ‘printf’

and clang:

x.c:3:6: warning: implicitly declaring library function 'printf' with type
      'int (const char *, ...)'
     printf("%d\n", 42);
     ^
x.c:3:6: note: include the header <stdio.h> or explicitly provide a declaration
      for 'printf'

(Neither does it for every undefined symbol, but it's a start.)
<snip>
-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#104074

FromGOTHIER Nathan <nathan.gothier@gmail.com>
Date2017-02-17 18:09 +0100
Message-ID<20170217180942.189815f43b612e8f01559bb9@gmail.com>
In reply to#104069
On Fri, 17 Feb 2017 16:34:03 +0000
BartC <bc@freeuk.com> wrote:

> Some questions:
> 
> What are the implications (for a normal PC, not embedded devices) of 
> having everything in the standard headers already known to a compiler?
> 
> That is, as if every source file was prefixed with #includes for the 
> 20-odd standard C headers.
> 
> (And apart from the obvious differences, for example a module with a 
> missing #include compiles OK here, but won't compile elsewhere.)

Bad built-in definitions (macros, functions, etc) must be fixed in the compiler
code. Some multilanguage compiler with common specification may not detect
exceptions such as including headers content for good C is mandatory but not
for bad C (aka C++).


> There was another question but I can't remember what it was. In that 
> case, let's go with this: The C Standard summarises what's expected in 
> the standard headers, but typical headers contain all sorts of extra 
> junk, even the smaller ones (I think some of them want to half-implement 
> the library functions in the headers).
> 
> For example ctype.h ought to contain 14 function declarations, but 
> actual headers have from 60 to 360 lines.

Implementors of the C standard have the right to provide extensions since it
doesn't change any defined behaviour.

 
> The question: will a ctype.h with only 14 lines actually work? (It 
> appears to.)

You should reserve some lines for an include gard but if you only declare the
standard set of functions available with the <ctype.h> header, that should be
enough.

 
> (I'm planning to create my own set of headers, and want to keep them 
> minimal, and without bristling with #ifdefs to avoid defining the same 
> thing twice. I also intend to have the same headers work on both Windows 
> and Linux as much as possible.)
> 
> -- 
> Bartc

You should read the C standard again and again... since that's not a conforming
behaviour.

[toc] | [prev] | [next] | [standalone]


#104076

From"Rick C. Hodgin" <rick.c.hodgin@gmail.com>
Date2017-02-17 09:18 -0800
Message-ID<d7af3c44-e831-4324-a803-24a64cff10bd@googlegroups.com>
In reply to#104069
On Friday, February 17, 2017 at 11:34:17 AM UTC-5, Bart wrote:
> Some questions:
> 
> What are the implications (for a normal PC, not embedded devices) of 
> having everything in the standard headers already known to a compiler?
> 
> That is, as if every source file was prefixed with #includes for the 
> 20-odd standard C headers.
> 
> (And apart from the obvious differences, for example a module with a 
> missing #include compiles OK here, but won't compile elsewhere.)
> 
> There was another question but I can't remember what it was. In that 
> case, let's go with this: The C Standard summarises what's expected in 
> the standard headers, but typical headers contain all sorts of extra 
> junk, even the smaller ones (I think some of them want to half-implement 
> the library functions in the headers).
> 
> For example ctype.h ought to contain 14 function declarations, but 
> actual headers have from 60 to 360 lines.
> 
> The question: will a ctype.h with only 14 lines actually work? (It 
> appears to.)
> 
> (I'm planning to create my own set of headers, and want to keep them 
> minimal, and without bristling with #ifdefs to avoid defining the same 
> thing twice. I also intend to have the same headers work on both Windows 
> and Linux as much as possible.)

I think a new keyword would be desirable that then enables all C
standard headers to be included if/when referenced.  They should use
non-standard names for all internal resources, and everything externally
visible should become a reserved word (even when not used), emitting a
fatal diagnostic when used apart from the C standard declaration
reference.

Thank you,
Rick C. Hodgin

[toc] | [prev] | [next] | [standalone]


#104077

FromKeith Thompson <kst-u@mib.org>
Date2017-02-17 09:26 -0800
Message-ID<lnino8pw3y.fsf@kst-u.example.com>
In reply to#104069
BartC <bc@freeuk.com> writes:
[...]
> (I'm planning to create my own set of headers, and want to keep them 
> minimal, and without bristling with #ifdefs to avoid defining the same 
> thing twice. I also intend to have the same headers work on both Windows 
> and Linux as much as possible.)

Those #ifdefs are required if your aim is to have a conforming, or even
reasably usable, implemnetation.  See N1570 7.1.2p4.  And it's just 3 or
so extra lines for each header.

-- 
Keith Thompson (The_Other_Keith) kst-u@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"

[toc] | [prev] | [next] | [standalone]


#104078

FromBartC <bc@freeuk.com>
Date2017-02-17 17:53 +0000
Message-ID<o87d7a$r22$1@dont-email.me>
In reply to#104077
On 17/02/2017 17:26, Keith Thompson wrote:
> BartC <bc@freeuk.com> writes:
> [...]
>> (I'm planning to create my own set of headers, and want to keep them
>> minimal, and without bristling with #ifdefs to avoid defining the same
>> thing twice. I also intend to have the same headers work on both Windows
>> and Linux as much as possible.)
>
> Those #ifdefs are required if your aim is to have a conforming, or even
> reasably usable, implemnetation.  See N1570 7.1.2p4.  And it's just 3 or
> so extra lines for each header.

They're not just used as guards for each header. They're commonly used 
to control single #defines.

The set of includes below have from 300 to 3300 #if, #ifdef or #ifndefs 
depending on their host compiler. It's not the processing time, it just 
makes files look untidy.

Here's a typical #define guard from string.h of one compiler:

#ifndef NULL
#define NULL  ((void *)0)
#endif

(NULL lives in stddef.h according to the Standard. So a program that 
only has #include <string.h>, that uses NULL, will compile here, but may 
not compile elsewhere.

Also this is a rare example of gcc being simpler than other compilers, 
in merely defining NULL as 0 or 0LL.)

-------------------------------

  #include <assert.h>
  #include <complex.h>
  #include <ctype.h>
  #include <errno.h>
  #include <fenv.h>
  #include <float.h>
  #include <inttypes.h>
  //#include <iso646.h>
  #include <limits.h>
  #include <locale.h>
  #include <math.h>
  #include <setjmp.h>
  #include <signal.h>
  #include <stdarg.h>
  #include <stdbool.h>
  #include <stddef.h>
  #include <stdint.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
  #include <time.h>
  #include <wchar.h>
  #include <wctype.h>

-- 
bartc

[toc] | [prev] | [next] | [standalone]


#104080

Fromme <crisdunbar@gmail.com>
Date2017-02-17 10:23 -0800
Message-ID<4dd9eb2c-684d-4d93-84f3-039a3247625b@googlegroups.com>
In reply to#104078
On Friday, February 17, 2017 at 9:53:38 AM UTC-8, Bart wrote:

<snip>
 
> Here's a typical #define guard from string.h of one compiler:
> 
> #ifndef NULL
> #define NULL  ((void *)0)
> #endif
> 
> (NULL lives in stddef.h according to the Standard. So a program that 
> only has #include <string.h>, that uses NULL, will compile here, but may 
> not compile elsewhere.

Nope. According to the standard NULL is defined in string.h (as well as
multiple other standard headers).

[toc] | [prev] | [next] | [standalone]


#104081

FromBartC <bc@freeuk.com>
Date2017-02-17 18:45 +0000
Message-ID<o87g88$6jh$1@dont-email.me>
In reply to#104080
On 17/02/2017 18:23, me wrote:
> On Friday, February 17, 2017 at 9:53:38 AM UTC-8, Bart wrote:
>
> <snip>
>
>> Here's a typical #define guard from string.h of one compiler:
>>
>> #ifndef NULL
>> #define NULL  ((void *)0)
>> #endif
>>
>> (NULL lives in stddef.h according to the Standard. So a program that
>> only has #include <string.h>, that uses NULL, will compile here, but may
>> not compile elsewhere.
>
> Nope. According to the standard NULL is defined in string.h (as well as
> multiple other standard headers).

So it is. As is size_t and a few other types.

Which strikes me as a naff bit of design.

Perhaps they could all have been extracted into their own common header.

(Or even, as I suggested some years ago, just have one giant header for 
everything. Then most #ifs would disappear.)

-- 
bartc

[toc] | [prev] | [next] | [standalone]


#104082

FromGOTHIER Nathan <nathan.gothier@gmail.com>
Date2017-02-17 19:54 +0100
Message-ID<20170217195405.58a5e1b7a9384bc637d922ca@gmail.com>
In reply to#104081
On Fri, 17 Feb 2017 18:45:05 +0000
BartC <bc@freeuk.com> wrote:

> Perhaps they could all have been extracted into their own common header.
> 
> (Or even, as I suggested some years ago, just have one giant header for 
> everything. Then most #ifs would disappear.)
> 
> -- 
> bartc
> 
> 

The common header for NULL (and other definitions) is <stddef.h>. The fact that
NULL is defined in other headers can be the result of the <stddef.h> inclusion.

[toc] | [prev] | [next] | [standalone]


#104086

FromKeith Thompson <kst-u@mib.org>
Date2017-02-17 12:27 -0800
Message-ID<lnefywpnp3.fsf@kst-u.example.com>
In reply to#104082
GOTHIER Nathan <nathan.gothier@gmail.com> writes:
> On Fri, 17 Feb 2017 18:45:05 +0000
> BartC <bc@freeuk.com> wrote:
>> Perhaps they could all have been extracted into their own common header.
>> 
>> (Or even, as I suggested some years ago, just have one giant header for 
>> everything. Then most #ifs would disappear.)
>
> The common header for NULL (and other definitions) is <stddef.h>. The
> fact that NULL is defined in other headers can be the result of the
> <stddef.h> inclusion.

No, standard headers may not include each other (or must behave as
if they do not include each other) unless specifically permitted
or required to do so.

For example, NULL and size_t are defined in both <stddef.h> and
<stdio.h> (and in some other standard headers), but <stdio.h> may
not simply include <stddef.h>.  The declarations that are required
for both headers are *only* those that are required for <stdio.h>
-- for example setvbuf() has a parameter of type size_t.  <stdio.h>
may not define the offsetof() macro, either directly or indirectly.

-- 
Keith Thompson (The_Other_Keith) kst-u@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"

[toc] | [prev] | [next] | [standalone]


#104085

Fromjameskuyper@verizon.net
Date2017-02-17 11:38 -0800
Message-ID<be1e9fb7-fe78-4e4a-b144-e520e8f73129@googlegroups.com>
In reply to#104069
On Friday, February 17, 2017 at 11:34:17 AM UTC-5, Bart wrote:
> Some questions:
> 
> What are the implications (for a normal PC, not embedded devices) of 
> having everything in the standard headers already known to a compiler?
> 
> That is, as if every source file was prefixed with #includes for the 
> 20-odd standard C headers.
> 
> (And apart from the obvious differences, for example a module with a 
> missing #include compiles OK here, but won't compile elsewhere.)
> 
> There was another question but I can't remember what it was. In that 
> case, let's go with this: The C Standard summarises what's expected in 
> the standard headers, but typical headers contain all sorts of extra 
> junk, even the smaller ones (I think some of them want to half-implement 
> the library functions in the headers).
> 
> For example ctype.h ought to contain 14 function declarations, but 
> actual headers have from 60 to 360 lines.
> 
> The question: will a ctype.h with only 14 lines actually work? (It 
> appears to.)
> 
> (I'm planning to create my own set of headers, and want to keep them 
> minimal, and without bristling with #ifdefs to avoid defining the same 
> thing twice. I also intend to have the same headers work on both Windows 
> and Linux as much as possible.)

If you don't care about fully conforming to the C standard, you can do pretty much whatever you want.
If you do care about fully conforming (which would be an unusual position for you to take), then there's a number of difficulties.

The easiest to deal with is code that uses identifiers from the standard library headers, without #including those headers, and without providing it's own definition for those identifiers. Except for macros, virtually every use of those identifiers would count as a syntax error of some kind or other, for which a diagnostic is required. After issuing that diagnostic message, if the user chooses to try to execute the program, the behavior is undefined, so your implementation is free to do whatever it wants. In particular, it's free to behave as if the relevant standard header had been #included. Still, the whole point of your idea is to let people write their code that way, so issuing a diagnostic for every time they do so would get in the way of that goal.

There's a trivial solution. The standard only requires a single diagnostic, no matter how many different aspects of the code require a diagnostic. The standard does not require that the diagnostic provide any useful information about the reason it was issued, and the standard never prohibits generation of a diagnostic. Therefore, have your compiler generate a message saying "Thank you for using my compiler!" and in your documentation identify this as a diagnostic message. I'd recommend that your documentation include a complete list of situations for which a diagnostic is required by the standard, for which this message is the only diagnostic they will get - but the standard imposes no such requirement.

Standard macros are a more difficult issue to deal with. That's because the standard defines precisely what the behavior should be if they are NOT defined. Unless and until the relevant header has actually been #included, your compiler must behave during preprocessing as if none of the relevant macros had been #defined. #ifdef, #ifndef, and the defined() operator must behave accordingly. In #if directives, such macros must be replaced with 0. They must NOT be expanded when occurring in any other context. This would be pretty thoroughly inconsistent with your reasons for wanting to add such a feature to your compiler.

The third difficulty involves identifiers which do not count as being reserved unless the corresponding standard header is #included. This applies to all macro names, but also to any identifiers with file scope and internal linkage (I can't remember anything that fits in that last category). User code is entitled to use those identifiers for it's own macro names or for names with file scope, so if the relevant standard header has NOT been #included, your compiler must allow those identifiers to be redefined in that way.

All in all, implementation of this feature in a fully conforming fashion would seem to be pointless, given all the hoops you have to jump through to make it behave as if the headers had NOT been pre-#included, unless and until they actually are. From past experience with you, I'd expect you to deal with these issues by failing to fully conform.

[toc] | [prev] | [next] | [standalone]


#104088

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-02-17 20:49 +0000
Message-ID<87d1egee57.fsf@bsb.me.uk>
In reply to#104069
BartC <bc@freeuk.com> writes:

> What are the implications (for a normal PC, not embedded devices) of
> having everything in the standard headers already known to a compiler?

That's fine provided that knowledge is switched on at the right time.  A
call to (for example) printf must be diagnosed as an error if there is
no declaration in scope but after the magic line #include <stdio.h> the
compiler must behave as if it contains a declaration of that function.

If you go down the route of having the headers simply trigger the right
internal behaviour you must Take care with the actual scope.  This:

int main(void)
{
     {
#include <stdio.h>
     }
     printf("");
}

requires a diagnostic.

> That is, as if every source file was prefixed with #includes for the
> 20-odd standard C headers.

This is not fine for, amongst other reasons, the one given above.

> (And apart from the obvious differences, for example a module with a
> missing #include compiles OK here, but won't compile elsewhere.)

But is this odd.  That obvious difference is very important.  Not only
that, you can declare an int called offsetof provided the macro is not
defined and you can write double printf = 42; in a conforming program.

> There was another question but I can't remember what it was. In that
> case, let's go with this: The C Standard summarises what's expected in
> the standard headers, but typical headers contain all sorts of extra
> junk, even the smaller ones (I think some of them want to
> half-implement the library functions in the headers).
>
> For example ctype.h ought to contain 14 function declarations, but
> actual headers have from 60 to 360 lines.
>
> The question: will a ctype.h with only 14 lines actually work? (It
> appears to.)

You don't need any lines at all provided that simply seeing the #include
magically brings the declarations into the scope being processed.  Even
if there really is a file with the 14 declarations in it, you don't even
need include guards provided the implementation keeps track of what's
been seen and what has not.

In the long run, because the compiler must behave as if the headers
contains guarded declarations, it is almost always easier simply to
write them that way.

<snip>
-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#104089

Fromsupercat@casperkitty.com
Date2017-02-17 13:29 -0800
Message-ID<b148131f-42eb-4a39-a20a-53b3daefc872@googlegroups.com>
In reply to#104088
On Friday, February 17, 2017 at 2:49:49 PM UTC-6, Ben Bacarisse wrote:
> If you go down the route of having the headers simply trigger the right
> internal behaviour you must Take care with the actual scope.  This:
> 
> int main(void)
> {
>      {
> #include <stdio.h>
>      }
>      printf("");
> }
> 
> requires a diagnostic.

Could that requirement be satisfied by having #include <stdio.h> expand
to something that would only be valid at file scope?  I don't think the
Standard defines the behavior of including a standard header in any other
context, especially since I see no way a header implemented as an actual
include file with no extensions could yield any kind of sensible semantics.

> But is this odd.  That obvious difference is very important.  Not only
> that, you can declare an int called offsetof provided the macro is not
> defined and you can write double printf = 42; in a conforming program.

I know one could write "static double printf=42.0;", but could one export
a symbol "printf" without causing a conflict with the library routine?  An
implementation could make all library functions map to macros like:

   #define printf __stdio_printf

and thus avoid any conflicts with user code, but I don't think that is
normally done for library functions that were in C89.

> In the long run, because the compiler must behave as if the headers
> contains guarded declarations, it is almost always easier simply to
> write them that way.

Perhaps, though on systems with slow file I/O improving performance by
building header file functionality into the compiler may be easier than
trying to achieve the same level of performance improvement via other
means.

[toc] | [prev] | [next] | [standalone]


#104092

FromBartC <bc@freeuk.com>
Date2017-02-17 22:13 +0000
Message-ID<o87se2$hsg$1@dont-email.me>
In reply to#104088
On 17/02/2017 20:49, Ben Bacarisse wrote:
> BartC <bc@freeuk.com> writes:
>
>> What are the implications (for a normal PC, not embedded devices) of
>> having everything in the standard headers already known to a compiler?
>
> That's fine provided that knowledge is switched on at the right time.  A
> call to (for example) printf must be diagnosed as an error if there is
> no declaration in scope but after the magic line #include <stdio.h> the
> compiler must behave as if it contains a declaration of that function.
>
> If you go down the route of having the headers simply trigger the right
> internal behaviour you must Take care with the actual scope.  This:
>
> int main(void)
> {
>      {
> #include <stdio.h>
>      }
>      printf("");
> }

 > requires a diagnostic.
 >

When I took took out the include completely, three compilers out of six 
didn't give any diagnostic at all!

Scoped non-function names declared in stdio.h (eg FILE) would cause a 
problem, except for macro names (eg EOF) which always have scope to the 
end of the file (so EOF after the include is OK, not before).

I don't know if such things are going to be common practice enough to 
worry about. Valid code developed elsewhere would have the includes in 
the right place. The issue is developing code under such a system which 
encourages you to be lax (eg leaving out all such includes) which must 
then be put through a normal compiler to pick up those problems.

>> That is, as if every source file was prefixed with #includes for the
>> 20-odd standard C headers.

Well, I don't think anything stops anyone doing that. For the vast 
majority of programs, it shouldn't stop them working.

>
> This is not fine for, amongst other reasons, the one given above.
>
>> (And apart from the obvious differences, for example a module with a
>> missing #include compiles OK here, but won't compile elsewhere.)
>
> But is this odd.  That obvious difference is very important.  Not only
> that, you can declare an int called offsetof provided the macro is not
> defined and you can write double printf = 42; in a conforming program.

I think you can do the latter anyway, provided it's inside a block scope 
(with stdio.h included in an outer scope). ('printf' will still be an 
identifier in the user namespace; it won't become a keyword.)

>> The question: will a ctype.h with only 14 lines actually work? (It
>> appears to.)
>
> You don't need any lines at all provided that simply seeing the #include
> magically brings the declarations into the scope being processed.  Even
> if there really is a file with the 14 declarations in it, you don't even
> need include guards provided the implementation keeps track of what's
> been seen and what has not.
>
> In the long run, because the compiler must behave as if the headers
> contains guarded declarations, it is almost always easier simply to
> write them that way.

Yes, I think I'll have to have header contents defined in a way where 
they can come into existence, or be activated, only when the appropriate 
standard header is included.

(I haven't decided on a representation yet, except that a production 
program will probably have the header info embedded inside.)

-- 
bartc

[toc] | [prev] | [next] | [standalone]


#104096

FromNick Bowler <nbowler@draconx.ca>
Date2017-02-17 22:28 +0000
Message-ID<o87tds$amh$1@dont-email.me>
In reply to#104088
On Fri, 17 Feb 2017 20:49:40 +0000, Ben Bacarisse wrote:
> That's fine provided that knowledge is switched on at the right time.  A
> call to (for example) printf must be diagnosed as an error if there is
> no declaration in scope but after the magic line #include <stdio.h> the
> compiler must behave as if it contains a declaration of that function.
>
> If you go down the route of having the headers simply trigger the right
> internal behaviour you must Take care with the actual scope.  This:
> 
> int main(void)
> {
>      {
> #include <stdio.h>
>      }
>      printf("");
> }
> 
> requires a diagnostic.

I think a diagnostic is not required.  This code violates a "shall"
requirement outside of a constraint:

  C11§7.1.2p4:

    "... a [standard] header shall be included outside of any external
     declaration or definition ..."

and therefore the results of such an inclusion are undefined.  So I
think the implementation could reasonably make a printf declaration
visible globally when it sees #include <stdio.h>, without caring (much)
about scoping rules.

[toc] | [prev] | [next] | [standalone]


#104116

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-02-18 02:48 +0000
Message-ID<87poigcixw.fsf@bsb.me.uk>
In reply to#104096
Nick Bowler <nbowler@draconx.ca> writes:

> On Fri, 17 Feb 2017 20:49:40 +0000, Ben Bacarisse wrote:
>> That's fine provided that knowledge is switched on at the right time.  A
>> call to (for example) printf must be diagnosed as an error if there is
>> no declaration in scope but after the magic line #include <stdio.h> the
>> compiler must behave as if it contains a declaration of that function.
>>
>> If you go down the route of having the headers simply trigger the right
>> internal behaviour you must Take care with the actual scope.  This:
>> 
>> int main(void)
>> {
>>      {
>> #include <stdio.h>
>>      }
>>      printf("");
>> }
>> 
>> requires a diagnostic.
>
> I think a diagnostic is not required.  This code violates a "shall"
> requirement outside of a constraint:
>
>   C11§7.1.2p4:
>
>     "... a [standard] header shall be included outside of any external
>      declaration or definition ..."

I didn't know that.  Thanks.  It's been so since at least C89 so I
should have known, but it's never come up until now.

> and therefore the results of such an inclusion are undefined.  So I
> think the implementation could reasonably make a printf declaration
> visible globally when it sees #include <stdio.h>, without caring
> (much) about scoping rules.

Indeed.  All bets are off.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#104154

Fromsupercat@casperkitty.com
Date2017-02-18 10:26 -0800
Message-ID<dd980d14-d81f-4f2f-b72e-0c0b1b8bfdba@googlegroups.com>
In reply to#104116
On Friday, February 17, 2017 at 8:49:05 PM UTC-6, Ben Bacarisse wrote:
> Nick Bowler writes:
> >   C11§7.1.2p4:
> >
> >     "... a [standard] header shall be included outside of any external
> >      declaration or definition ..."
> 
> I didn't know that.  Thanks.  It's been so since at least C89 so I
> should have known, but it's never come up until now.

It might be useful for a C-like language to allow the effects of headers
to be limited to scoping blocks, but that could only work in a language
where the processing of #define or similar constructs was done by an entity
that understood the concept of nested scopes.  I see no way that a typical
C implementation could hope to achieve sensible semantics when given such
constructs.

[toc] | [prev] | [next] | [standalone]


#104155

Frombart4858@gmail.com
Date2017-02-18 11:08 -0800
Message-ID<19e0feb6-71d5-4fef-9a02-39eb6738db84@googlegroups.com>
In reply to#104154
On Saturday, 18 February 2017 18:26:50 UTC, supe...@casperkitty.com  wrote:
> On Friday, February 17, 2017 at 8:49:05 PM UTC-6, Ben Bacarisse wrote:
> > Nick Bowler writes:
> > >   C11§7.1.2p4:
> > >
> > >     "... a [standard] header shall be included outside of any external
> > >      declaration or definition ..."
> > 
> > I didn't know that.  Thanks.  It's been so since at least C89 so I
> > should have known, but it's never come up until now.
> 
> It might be useful for a C-like language to allow the effects of headers
> to be limited to scoping blocks, but that could only work in a language
> where the processing of #define or similar constructs was done by an entity
> that understood the concept of nested scopes.  I see no way that a typical
> C implementation could hope to achieve sensible semantics when given such
> constructs.

Lots of things going on here. You have include files, which are a general lexical feature which can be applied anywhere. And you have headers doing the job of 'import', which are generally put at the top of a file.

Just because a general-purpose include can be done anywhere, doesn't mean you should stick a header 12 levels deep inside a block (or worse, have hundreds of the same header included in different local blocks. That would be just be silly. C headers are that way to mitigate the effects of just including everything that defines the language.

Designed a little differently, everything in the headers would just be built-in to every program.

Then there are #defines, another lexical feature defining a name that exists outside of any static scopes. That means the same macro names defined in subsequence scopes would interfere with each other. #undef can be used to some extent, but it doesn't work in the general case (nested blocks for example).

So I say forget about having headers inside blocks. Just use them as though they were imports, and with all names having file scope.

-- 
bartc

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | comp.lang.c


csiph-web