简体   繁体   中英

C Standard Conformance - Identifiers

I'm looking for some clarifications on parts of the C Standard (C99 and/or C11), mainly on the use of identifiers .
The context is the implementation of a complete C99 standard library, which I want it to be fully compliant with the standard.

The basic question is: to what extend am I allowed by the C standard to declare identifiers/symbols not listed in the standard?

As an example, let's consider the isfinite macro from math.h .
A possible implementation might be:

#define isinf( _x_ )                                                       \
    (                                                                      \
        ( sizeof( _x_ ) == sizeof( float  ) ) ? _c99_math_isinf_f( _x_ ) : \
        ( sizeof( _x_ ) == sizeof( double ) ) ? _c99_math_isinf_d( _x_ ) : \
                                                _c99_math_isinf_l( _x_ )   \
    )

int _c99_math_isinf_f( float x );
int _c99_math_isinf_d( double x );
int _c99_math_isinf_l( long double x );

Here I need to declare additional identifiers that are obviously not part of the C standard.

In note 3 of section 4 of the C99 standard ( Conformance ), we can read:

This implies that a conforming implementation reserves no identifiers other than those explicitly reserved in this International Standard.

I'm not sure to understand it.
Does it mean I'm not allowed to declare additional identifiers?

Assuming that it's not the case, and that I am allowed to declare other identifiers for my own implementation, what naming rule should I follow , considering those identifiers are not meant to be used other than in a macro expansion, like the above example?

In section 7.1.3 of the C99 standard ( Reserved identifiers ), we can read:

  1. All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use.
  2. All identifiers that begin with an underscore are always reserved for use as identifiers with file scope in both the ordinary and tag name.

Ok, I shall not declare an identifier with leading double underscore, nor a leading single underscore followed by an uppercase letter.
But what about the second rule, still considering my above example?

The point of the reserved identifiers rule is that those identifiers are reserved for the implementation. Now that you are writing (part of) the implementation rather than an "end user program", you should name your identifiers in the reserved name space, exactly so that your identifiers don't accidentally collide with the identifiers of the (eventual) end user.

As an example of this rule in action, if you're on Linux, use "readelf -s" to check the symbol lists of, say, glibc or libgcc. You'll find plenty of symbols with leading double underscores, or leading underscore followed by a capital letter.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM