Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #104069 > unrolled thread
| Started by | BartC <bc@freeuk.com> |
|---|---|
| First post | 2017-02-17 16:34 +0000 |
| Last post | 2017-02-19 16:00 -0800 |
| Articles | 20 on this page of 24 — 12 participants |
Back to article view | Back to comp.lang.c
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 →
| From | BartC <bc@freeuk.com> |
|---|---|
| Date | 2017-02-17 16:34 +0000 |
| Subject | Standard 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]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2017-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]
| From | luser droog <luser.droog@gmail.com> |
|---|---|
| Date | 2017-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2017-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]
| From | GOTHIER Nathan <nathan.gothier@gmail.com> |
|---|---|
| Date | 2017-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]
| From | "Rick C. Hodgin" <rick.c.hodgin@gmail.com> |
|---|---|
| Date | 2017-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]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2017-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]
| From | BartC <bc@freeuk.com> |
|---|---|
| Date | 2017-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]
| From | me <crisdunbar@gmail.com> |
|---|---|
| Date | 2017-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]
| From | BartC <bc@freeuk.com> |
|---|---|
| Date | 2017-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]
| From | GOTHIER Nathan <nathan.gothier@gmail.com> |
|---|---|
| Date | 2017-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]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2017-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]
| From | jameskuyper@verizon.net |
|---|---|
| Date | 2017-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2017-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]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2017-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]
| From | BartC <bc@freeuk.com> |
|---|---|
| Date | 2017-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]
| From | Nick Bowler <nbowler@draconx.ca> |
|---|---|
| Date | 2017-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2017-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]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2017-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]
| From | bart4858@gmail.com |
|---|---|
| Date | 2017-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