Macros that break compiler headers

G

Grumble

Hello,

I recently came across code that defined a peculiar macro:

#define local static

gcc had no problem with it, but another (experimental) compiler I am
evaluating output a lengthy list of errors.

Apparently, the identifier 'local' is used in several places within that
compiler's headers. Hell breaks loose when the identifier is changed to
a reserved keyword.

Should the compiler implementers be more careful in their choice of
identifiers, or is the macro definition somehow illegal?
 
L

Lawrence Kirby

Hello,

I recently came across code that defined a peculiar macro:

#define local static

gcc had no problem with it, but another (experimental) compiler I am
evaluating output a lengthy list of errors.

Apparently, the identifier 'local' is used in several places within that
compiler's headers. Hell breaks loose when the identifier is changed to
a reserved keyword.

Should the compiler implementers be more careful in their choice of
identifiers, or is the macro definition somehow illegal?

It looks fine to me. I couldn't find any sets of reserved identifiers that
can match local. So the implementation should not be using it.

Lawrence
 
K

Kenny McCormack

Apparently, the identifier 'local' is used in several places within that
compiler's headers. Hell breaks loose when the identifier is changed to
a reserved keyword.

Should the compiler implementers be more careful in their choice of
identifiers, or is the macro definition somehow illegal?

It looks fine to me. I couldn't find any sets of reserved identifiers that
can match local. So the implementation should not be using it.[/QUOTE]

But that does leave open this gap - which I find annoying - in C. Which is
that you can't ever really be sure what is reserved and what isn't - other
than by constantly keeping up with standards documents and/or posting (and
getting flamed) here.

The OP posted a similar item in c.u.p. about code that defined (or
typedef'd - not sure which) the word "stat" and this caused problems
(basically, because the "experimental compiler" automatically included
stat.h). It seems to me that languages ought to make better provisions for
separating the programmers and implementors namespaces. I suppose it is
too late for C.

Would it work if all user symbols started with a capital letter?
 
R

Richard Bos

Grumble said:
I recently came across code that defined a peculiar macro:

#define local static

gcc had no problem with it, but another (experimental) compiler I am
evaluating output a lengthy list of errors.

Apparently, the identifier 'local' is used in several places within that
compiler's headers. Hell breaks loose when the identifier is changed to
a reserved keyword.

Should the compiler implementers be more careful in their choice of
identifiers, or is the macro definition somehow illegal?

It's the implementation's fault. It would probably have the same, or
similar, problems with declarations like

int *local;

or

void local(char *txt, int len);

placed before its headers. All of those, including your #define, are
perfectly legal; the implementation is to keep its paws off identifiers
which are not reserved for its use, of which local is one.

Richard
 
R

Richard Bos

But that does leave open this gap - which I find annoying - in C. Which is
that you can't ever really be sure what is reserved and what isn't - other
than by constantly keeping up with standards documents and/or posting (and
getting flamed) here.

Constantly? There's only two Standards, plus a couple of DRs which,
TTBOMK, don't add any reserved identifiers. How hard is it to keep up
with those?
The OP posted a similar item in c.u.p. about code that defined (or
typedef'd - not sure which) the word "stat" and this caused problems
(basically, because the "experimental compiler" automatically included
stat.h).

Then that compiler is broken, not the code.
Would it work if all user symbols started with a capital letter?

Absolutely not. I refuse to make my code uglier for no good reason. If
you want to go that way at all, you should make all implementation
symbols start with a capital, since there are fewer of them than there
are user symbols. Even that would be a pain, since I now like to use
capitalised names for those occasions when I use typedef.

Richard
 
M

Mark McIntyre

On Thu, 16 Dec 2004 13:24:51 GMT, in comp.lang.c ,
But that does leave open this gap - which I find annoying - in C. Which is
that you can't ever really be sure what is reserved and what isn't

Show me a language in which this isn't the case.
- other
than by constantly keeping up with standards documents and/or posting (and
getting flamed) here.

And.... ?
 
D

Dik T. Winter

> On Thu, 16 Dec 2004 13:24:51 GMT, in comp.lang.c ,
> (e-mail address removed) (Kenny McCormack) wrote:
>
>
> Show me a language in which this isn't the case.

Algol 60, Fortran.
 
R

Richard Bos

Dik T. Winter said:
Algol 60, Fortran.

From the 1977 Fortran Standard:

# A2. Conflicts with ANSI X3.9-1966

# (22) More intrinsic function names have been added and could conflict
# with the names of subprograms. These names are ACOS, ANINT, ASIN,
# CHAR, COSH, DACOS, DASIN, DCOSH, DDIM, DINT, DNINT, DPROD,
# DSINH, DTAN, DTANH, ICHAR, IDNINT, INDEX, LEN, LGE, LGT,
# LLE, LLT, LOG, LOG10, MAX, MIN, NINT, SINH, and TAN.

I don't see how this is different from the situation with C89 and C99.
As for Algol 60, specifying the year is cheating. You might as well say
that there are no different versions of C89.

Richard
 
G

Grumble

Richard said:
It's the implementation's fault. It would probably have the same, or
similar, problems with declarations like

int *local;

or

void local(char *txt, int len);

placed before its headers.

As far as I understand, 'local' is only used as an auto variable in
the compiler's implementation. Thus your two examples would not be a
problem, right?
All of those, including your #define, are perfectly legal; the
implementation is to keep its paws off identifiers which are not
reserved for its use, of which local is one.

OK. What about

#define int const long
#define unsigned
#define extern static
#define double my_double
#define else

I imagine /they/ are explicitely forbidden?
 
D

Dik T. Winter

....
> From the 1977 Fortran Standard:
>
> # A2. Conflicts with ANSI X3.9-1966
>
> # (22) More intrinsic function names have been added and could conflict
> # with the names of subprograms. These names are ACOS, ANINT, ASIN,
> # CHAR, COSH, DACOS, DASIN, DCOSH, DDIM, DINT, DNINT, DPROD,
> # DSINH, DTAN, DTANH, ICHAR, IDNINT, INDEX, LEN, LGE, LGT,
> # LLE, LLT, LOG, LOG10, MAX, MIN, NINT, SINH, and TAN.
>
> I don't see how this is different from the situation with C89 and C99.

But those are *not* reserved names. You can use them (even as a subprogram)
in a way completely unrelated to the standard definition. This is not
different from other languages that come with a standard library and where
you use a function with the same name as a function in the library.
> As for Algol 60, specifying the year is cheating. You might as well say
> that there are no different versions of C89.

Why is it cheating? Algol 68 is a completely different language. In
all the versions of Algol 60 the set of reserved names is identical
(it is empty).
 
C

CBFalconer

Grumble said:
Richard Bos wrote:
.... snip ...


OK. What about

#define int const long
#define unsigned
#define extern static
#define double my_double
#define else

I imagine /they/ are explicitely forbidden?

Exactly. If you don't want the standard in pdf form, and want to
be able to use text utilities such as grep on it, download
N869.txt. Google for its location.
 
G

Grumble

CBFalconer said:
Exactly. If you don't want the standard in pdf form, and want
to be able to use text utilities such as grep on it, download
N869.txt. Google for its location.

Thanks for the pointer ;-)

I skimmed section 6.10 (Preprocessing directives).
Am I looking in the right place?
 
D

Dik T. Winter

> On Fri, 17 Dec 2004 00:57:52 GMT, in comp.lang.c , "Dik T. Winter"

>
> And you can absolutely guatantee that NO future evolution of either
> language will need to adopt new keywords.

They will adopt new keywords, but they will *not* adopt new reserved words.
The reason is that both do no have reserved words. In Algol 60 in all its
variants keywords can be distinguished from other "words". In Fortran a
keyword is only recognised when it is in the correct syntactical position.
From an article I wrote back in 1996:
> I once wrote a Fortran program which
> ended something like this:
> IF(IF .EQ. EQ THEN) THEN
> CALL CALL(END)
> END IF
> IF = PRINT
> PRINT *, END
> END
> the stuttering program, every keyword was repeated with a different meaning,
> and the actual version made some sense.

You may compile the above with a Fortran compiler and see it compiles (but
does not link, because the subroutine call is not provided).
 
D

Dave Thompson

Before/when you #include any standard header, which was the situation
you asked about upthread. Or at least you said the compiler's headers,
which might mean implementation-added ones rather than standard, but
implementation-added headers are already Undefined in the standard.

You can do this sort of nonsense strictly within your own code if you
want. You will be deservedly condemned and shunned by all sensible
people, and you will probably drive yourself crazy if you aren't
already, but you won't be violating the standard and it will work.
Thanks for the pointer ;-)

I skimmed section 6.10 (Preprocessing directives).
Am I looking in the right place?

7.1.2p4.


- David.Thompson1 at worldnet.att.net
 
L

Lawrence Kirby

Before/when you #include any standard header, which was the situation
you asked about upthread. Or at least you said the compiler's headers,
which might mean implementation-added ones rather than standard, but
implementation-added headers are already Undefined in the standard.

You can do this sort of nonsense strictly within your own code if you
want.

However you get undefined behaviour, at least I think so. C99 6.4.1p2 says

"The above tokens (case sensitive) are reserved (in translation phases 7
and 8) for use as keywords, and shall not be used otherwise."

The question is whether the "and shall not be used otherwise" restriction
is limited to translation phases 7 and 8. I don't think it can be because
if that was so there wouldn't be nothing to prevent the redefinition of
keywords before including standard headers.
You will be deservedly condemned and shunned by all sensible
people, and you will probably drive yourself crazy if you aren't
already, but you won't be violating the standard and it will work.

Of course it is great for IOCCC entries.

I don't see anything in 7.1.2 (or 7.1.3 for that matter) that prohibits
keywords being #defined prior to inclusion of standard headers. So unless
there's something else I missed we're left with 6.4.1.p2. And that doesn't
make any distinction about where the definition occurs; if #defining a
keyword is undefined it is undefined in all contexts.

Lawrence
 
D

Dave Thompson

However you get undefined behaviour, at least I think so. C99 6.4.1p2 says

"The above tokens (case sensitive) are reserved (in translation phases 7
and 8) for use as keywords, and shall not be used otherwise."

The question is whether the "and shall not be used otherwise" restriction
is limited to translation phases 7 and 8. I don't think it can be because
if that was so there wouldn't be nothing to prevent the redefinition of
keywords before including standard headers.
Sorry, but I think it has to be limited to phase 7 & 8 because only
then are _tokens_ distinguished into keywords and identifiers; before
that you just have identifier(ish) pp-tokens. 6.4p3; 6.4.2.1p4.
Of course it is great for IOCCC entries.
No comment on juxtaposing the concepts 'sensible' and 'IOCCC' :)

I don't see anything in 7.1.2 (or 7.1.3 for that matter) that prohibits
keywords being #defined prior to inclusion of standard headers. So unless
there's something else I missed we're left with 6.4.1.p2. And that doesn't
make any distinction about where the definition occurs; if #defining a
keyword is undefined it is undefined in all contexts.
Last sentence of p4: The program shall not have any
macros with names lexically identical to keywords currently defined
prior to the
inclusion [of a standard header].

Formally 'prior' could be ambiguous, but I think it's clear this means
"immediately before the point of the source, as preprocessed so far,
where the #include directive occurs". (Given a suitable definition of
'preprocessed'.) It's not a constraint, so violating it is UB.

- David.Thompson1 at worldnet.att.net
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top