By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,011 Members | 2,968 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,011 IT Pros & Developers. It's quick & easy.

Can #include use a preprocessing token?

P: n/a
Can #include safely use a preprocessing token, as in

#define HEADERFILE "stdio.h"
#include HEADERFILE
int main(void) {return printf("Hello, world\n")*0;}
TIA,

François Grieu
Nov 14 '05 #1
Share this Question
Share on Google+
12 Replies


P: n/a
Francois Grieu wrote:
Can #include safely use a preprocessing token, as in

#define HEADERFILE "stdio.h"
#include HEADERFILE
int main(void) {return printf("Hello, world\n")*0;} cat main.c #define HEADERFILE "stdio.h"

#include HEADERFILE

int main(int argc, char* argv[]) {
return printf("Hello, world!\n")*0;
}
gcc -Wall -std=c99 -pedantic -o main main.c
./main

Hello, world!

Why, yes! It appears that you can.
Nov 14 '05 #2

P: n/a
"E. Robert Tisdale" <E.**************@jpl.nasa.gov> wrote:
Francois Grieu wrote:
Can #include safely use a preprocessing token, as in

#define HEADERFILE "stdio.h"
#include HEADERFILE
int main(void) {return printf("Hello, world\n")*0;}

> cat main.c

#define HEADERFILE "stdio.h"

#include HEADERFILE

int main(int argc, char* argv[]) {
return printf("Hello, world!\n")*0;
}
> gcc -Wall -std=c99 -pedantic -o main main.c
> ./main

Hello, world!

Why, yes! It appears that you can.


Well, no. It appears that you can _using GCC_. Given the rather severe
embrace-and-extend habits of the Gnu people, this tells you absolutely
nothing about ISO C.

Of course, you _can_ actually do the above in ISO C, and you don't even
need a C99 compiler for that, as your command line seems to suggest. But
that conclusion can be drawn from the definition of the #include
directive in the ISO C Standard, _not_ from a test using Ganuck.

Richard
Nov 14 '05 #3

P: n/a
Francois Grieu <fg****@francenet.fr> wrote:
Can #include safely use a preprocessing token, as in

#define HEADERFILE "stdio.h"
#include HEADERFILE
int main(void) {return printf("Hello, world\n")*0;}


Yes.

ISO/IEC 9899:1999
6.10.2 Source file inclusion
[...]
4 A preprocessing directive of the form
# include pp-tokens new-line
(that does not match one of the two previous forms) is permitted.
The preprocessing tokens after include in the directive are
processed just as in normal text. (Each identifier currently
defined as a macro name is replaced by its replacement list of
preprocessing tokens.) The directive resulting after all
replacements shall match one of the two previous forms.
[...]

Regards.
--
Irrwahn Grausewitz (ir*******@freenet.de)
welcome to clc: http://www.ungerhu.com/jxh/clc.welcome.txt
clc faq-list : http://www.faqs.org/faqs/C-faq/faq/
clc OT guide : http://benpfaff.org/writings/clc/off-topic.html
Nov 14 '05 #4

P: n/a
Richard Bos wrote:
E. Robert Tisdale wrote:
Francois Grieu wrote:
Can #include safely use a preprocessing token, as in

#define HEADERFILE "stdio.h"
#include HEADERFILE
int main(void) {return printf("Hello, world\n")*0;}
> cat main.c

#define HEADERFILE "stdio.h"

#include HEADERFILE

int main(int argc, char* argv[]) {
return printf("Hello, world!\n")*0;
}
> gcc -Wall -std=c99 -pedantic -o main main.c
> ./main

Hello, world!

Why, yes! It appears that you can.


Well, no. It appears that you can _using GCC_.
Given the rather severe
embrace-and-extend habits of the Gnu people,
this tells you absolutely nothing about ISO C.

Of course, you _can_ actually do the above in ISO C,
and you don't even need a C99 compiler for that,
as your command line seems to suggest.


My command line suggests no such thing.
But that conclusion can be drawn
from the definition of the #include directive in the ISO C Standard,
_not_ from a test using Ganuck.


Pardon me Richard,
but I'll trust the GNU compiler developers
over some pretentious ass who "draws conclusions"
from his personal interpretation of the ISO C standard any day.
Nov 14 '05 #5

P: n/a

On Wed, 9 Jun 2004, Richard Bos wrote:

Trollsdale wrote:
Francois Grieu wrote:
Can #include safely use a preprocessing token, as in

#define HEADERFILE "stdio.h"
#include HEADERFILE
int main(void) {return printf("Hello, world\n")*0;}
<snip garbage> Why, yes! It appears that you can.


Well, no. It appears that you can _using GCC_. Given the rather severe
embrace-and-extend habits of the Gnu people, this tells you absolutely
nothing about ISO C.


In fact, AFAICT the OP's code is *not* correct. Since when is

#include "stdio.h"

the appropriate way to get a prototype in scope for 'printf', a function
defined in the header <stdio.h>? The OP's code would be perfectly
correct were he to have written

#define HEADERFILE <stdio.h>
#include HEADERFILE

-Arthur

--
please don't feed the trollsdale, not even if he replies to you
<cough>Christian Bau</cough>
Nov 14 '05 #6

P: n/a
On Wed, 9 Jun 2004 09:36:41 -0400 (EDT), "Arthur J. O'Dwyer"
<aj*@nospam.andrew.cmu.edu> wrote:

On Wed, 9 Jun 2004, Richard Bos wrote:

Trollsdale wrote:
> Francois Grieu wrote:
>
> > Can #include safely use a preprocessing token, as in
> >
> > #define HEADERFILE "stdio.h"
> > #include HEADERFILE
> > int main(void) {return printf("Hello, world\n")*0;}<snip garbage> > Why, yes! It appears that you can.


Well, no. It appears that you can _using GCC_. Given the rather severe
embrace-and-extend habits of the Gnu people, this tells you absolutely
nothing about ISO C.


In fact, AFAICT the OP's code is *not* correct. Since when is

#include "stdio.h"

the appropriate way to get a prototype in scope for 'printf', a function
defined in the header <stdio.h>? The OP's code would be perfectly
correct were he to have written

#define HEADERFILE <stdio.h>
#include HEADERFILE

-Arthur


I was under the impression that "stdio.h" and <stdio.h> could both
reference the same file, but that the <> instructed the preprocessor
to look in a implementation defined location for said file, while ""
is 'look in the current directory, then in any implementation defined
locations'.

So if the pp doesn't find stdio.h in the current directory, it's well
within its rights to look elsewhere.

Am I mistaken?

--
Andrew

Nov 14 '05 #7

P: n/a
"Arthur J. O'Dwyer" <aj*@nospam.andrew.cmu.edu> wrote:
In fact, AFAICT the OP's code is *not* correct. Since when is

#include "stdio.h"

the appropriate way to get a prototype in scope for 'printf', a function
defined in the header <stdio.h>? The OP's code would be perfectly
correct were he to have written

#define HEADERFILE <stdio.h>
#include HEADERFILE


From (a draft of) C89:

# A preprocessing directive of the form
#
# # include "q-char-sequence" new-line
#
#causes the replacement of that directive by the entire contents of the
#source file identified by the specified sequence between the
#delimiters. The named source file is searched for in an
#implementation-defined manner. If this search is not supported, or if
#the search fails, the directive is reprocessed as if it read
#
# # include <h-char-sequence> new-line
#
#with the identical contained sequence (including > characters, if any)
#from the original directive.

Richard
Nov 14 '05 #8

P: n/a

On Wed, 9 Jun 2004, Richard Bos wrote:

"Arthur J. O'Dwyer" <aj*@nospam.andrew.cmu.edu> wrote:
In fact, AFAICT the OP's code is *not* correct. Since when is

#include "stdio.h"

the appropriate way to get a prototype in scope for 'printf', a function
defined in the header <stdio.h>?


From (a draft of) C89:
#
# A preprocessing directive of the form
#
# # include "q-char-sequence" new-line
#
#causes the replacement of that directive by the entire contents of the
#source file identified by the specified sequence between the
#delimiters. The named source file is searched for in an
#implementation-defined manner. If this search is not supported, or if
#the search fails, the directive is reprocessed as if it read
#
# # include <h-char-sequence> new-line


Okay. So it's implementation-defined whether it's correct (depending
on whether the implementation defines the search for "stdio.h" to
succeed, in which case consult your documentation, or fail, in which
case the code is correct).
Still, the portably correct way is <stdio.h>, which AFAIK is
guaranteed to succeed on any hosted implementation.

-Arthur
Nov 14 '05 #9

P: n/a
E. Robert Tisdale wrote:
Richard Bos wrote:
E. Robert Tisdale wrote:
> gcc -Wall -std=c99 -pedantic -o main main.c
Of course, you _can_ actually do the above in ISO C,
and you don't even need a C99 compiler for that, as your command line
seems to suggest.
My command line suggests no such thing.


The troll ERT used the -std=c99 option intending, it seems, to invoke
gcc in C89 mode.
Nov 14 '05 #10

P: n/a
Martin Ambuhl wrote:
ERT used the -std=c99 option
intending, it seems, to invoke gcc in C89 mode.


That's a lie.

Go away troll.
Nov 14 '05 #11

P: n/a
On Wed, 09 Jun 2004 14:06:37 GMT, rl*@hoekstra-uitgeverij.nl (Richard
Bos) wrote in comp.lang.c:
"Arthur J. O'Dwyer" <aj*@nospam.andrew.cmu.edu> wrote:
In fact, AFAICT the OP's code is *not* correct. Since when is

#include "stdio.h"

the appropriate way to get a prototype in scope for 'printf', a function
defined in the header <stdio.h>? The OP's code would be perfectly
correct were he to have written

#define HEADERFILE <stdio.h>
#include HEADERFILE


From (a draft of) C89:

# A preprocessing directive of the form
#
# # include "q-char-sequence" new-line
#
#causes the replacement of that directive by the entire contents of the
#source file identified by the specified sequence between the
#delimiters. The named source file is searched for in an
#implementation-defined manner. If this search is not supported, or if
#the search fails, the directive is reprocessed as if it read
#
# # include <h-char-sequence> new-line
#
#with the identical contained sequence (including > characters, if any)
#from the original directive.

Richard


Your quotation is basically correct, but your conclusion is not,
according to the standard. It happens to work on most
implementations, because the C standard headers are supplied as text
files for the majority of them.

Here is the relevant text from the C99 standard, including material
above what you quoted:

<begin quote>
6.10.2 Source file inclusion

Constraints
1 A #include directive shall identify a header or source file that can
be processed by the implementation.

Semantics
2 A preprocessing directive of the form
# include <h-char-sequence> new-line
searches a sequence of implementation-defined places for a header
identified uniquely by the specified sequence between the < and >
delimiters, and causes the replacement of that directive by the entire
contents of the header. How the places are specified or the header
identified is implementation-defined.

3 A preprocessing directive of the form
# include "q-char-sequence" new-line
causes the replacement of that directive by the entire contents of the
source file identified by the specified sequence between the "
delimiters. The named source file is searched for in an
implementation-defined manner. If this search is not supported, or if
the search fails, the directive is reprocessed as if it read
# include <h-char-sequence> new-line
with the identical contained sequence (including > characters, if any)
from the original directive.
<end quote>

Note the distinction between "headers" (which need not be files) which
are included with the #include <> directive, and source files which
may be included with the #include "" directive.

There is no guarantee that:

#include "stdio.h"

....will include the standard C header <stdio.h> into the source and
make the corresponding library functions available with proper
prototypes.

Specifically, if the implementation-defined methods of search and file
or file identification happen to come across some random file _not_
provided by the implementation as a standard header, and includes it
as a source file, the behavior is completely undefined.

#include <stdio.h>

....is conforming and guaranteed to properly include the standard
header.

#include "stdio.h"

....is not, and is not required to be accepted by a conforming
implementation.

This is true of all 15, 18, or 24 standard headers for C89/90, 95, and
99 respectively.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Nov 14 '05 #12

P: n/a
Jack Klein <ja*******@spamcop.net> wrote:
On Wed, 09 Jun 2004 14:06:37 GMT, rl*@hoekstra-uitgeverij.nl (Richard
Bos) wrote in comp.lang.c:
From (a draft of) C89:

# A preprocessing directive of the form
#
# # include "q-char-sequence" new-line
#
#causes the replacement of that directive by the entire contents of the
#source file identified by the specified sequence between the
#delimiters. The named source file is searched for in an
#implementation-defined manner. If this search is not supported, or if
#the search fails, the directive is reprocessed as if it read
#
# # include <h-char-sequence> new-line
#
#with the identical contained sequence (including > characters, if any)
#from the original directive.
Your quotation is basically correct,


It is perfectly correct; it is a direct copy and paste. It is not,
however, C99.
Here is the relevant text from the C99 standard, including material
above what you quoted:

<begin quote>
6.10.2 Source file inclusion
[ Snip quote ]
Note the distinction between "headers" (which need not be files) which
are included with the #include <> directive, and source files which
may be included with the #include "" directive. Specifically, if the implementation-defined methods of search and file
or file identification happen to come across some random file _not_
provided by the implementation as a standard header, and includes it
as a source file, the behavior is completely undefined.


Ah, but...

# [#3] If a file with the same name as one of the above < and
# > delimited sequences, not provided as part of the
# implementation, is placed in any of the standard places that
# are searched for included source files, the behavior is
# undefined.

That's from n869, 7.1.2. C99 has the same text, AFAIK.

So if that file is found, _that file_ causes the undefined behaviour.
For an otherwise well-conforming program, i.e. one which does _not_ have
this UB-causing file, #include "stdio.h" is required to fall through to
<stdio.h>.

Richard
Nov 14 '05 #13

This discussion thread is closed

Replies have been disabled for this discussion.