Tim Rentsch
10/21/2009 9:09:00 AM
Eric Sosman <Eric.Sosman@sun.com> writes:
> Tim Rentsch wrote:
>> Eric Sosman <Eric.Sosman@sun.com> writes:
>>
>>> Francois Grieu wrote:
>>>> Is the following program correct?
>>>>
>>>> /* SOF on this line 1 */
>>>> #ifndef TABLE
>>>> char *gStr[] = {
>>>> #define TABLE( str, num1, num2 ) str,
>>>> #include __FILE__
>>> Sneaky, but I think there are at least two potential problems:
>>>
>>> First, the mapping of __FILE__'s expansion to a header file name
>>> is implementation-defined (6.10.2p4). So even if __FILE__ expands
>>> to "foobar.h" it is not necessarily the case that #include __FILE__
>>> and #include "foobar.h" work identically.
>>
>> The provision in 6.10.2p4 doesn't apply. The __FILE__ macro
>> expands to a character string literal, not to a sequence of
>> preprocessing tokens with (") characters around it. Thus
>> it's already a single preprocessing-token, with no need to
>> have to combine anything to get a header name.
>
> In #include "foobar.h" the stuff after #include is a header-name
> preprocessing token, something that is recognized only in #include
> directives (6.4.7p3).
Also in #pragma directives in some cases, but close enough.
> In #include __FILE__ the stuff after #include is not a header-
> name preprocessing token, but an identifier (6.4.2), a macro name.
> Nor is its expansion a header-name, because __FILE__ expands to a
> string literal (6.10.8p1). A string literal is not a header-name
> (6.4p1, 6.4.5, 6.4.7), so it is necessary to apply some kind of
> transformation to the expansion of __FILE__ to make a header-name
> out of it. 6.10.2p4 says that the transformation is implementation-
> defined.
First, what Keith Thompson said -- 6.10.2p4 is not talking about
the case of string literals, because a string literal is a single
preprocessing token, not a sequence of preprocessing tokens between
a pair of " characters.
Second, I think you may be hallucinating. The syntax for #include
doesn't mention header-name anywhere. It just happens that a
header-name is a preprocessing token that happens to have the
right form. But a string literal preprocessing token also has the
right form (as long as it doesn't have a " in it). Hence, after
macro expansion, the directive matches one of the two previous
forms (specifically, the <<# include "q-char-sequence" new-line>>
form). So what happens with a single string literal after
macro expansion is well-defined.
> Besides, if 6.10.2p4 did not apply, #include __FILE__ would be
> an error right from the start. Delete 6.10.2p4 from the Standard,
> and you're left with #include <foo.h> and #include "bar.h" as the
> only two valid forms. #include __FILE__ matches neither.
When I said "The provision in 6.10.2p4 doesn't apply", the
provision I was talking about is the implementation-defined
mapping mentioned in the last sentence. Of course the previous
sentences apply.