I'm a tad confused between what is and is not a Constant Expression in C, even after much Googleing. Could you provide an example of something which is, and which is not, a Constant Expression in C?
相关问题
- Multiple sockets for clients to connect to
- What is the best way to do a search in a large fil
- glDrawElements only draws half a quad
- Index of single bit in long integer (in C) [duplic
- Equivalent of std::pair in C
Nobody seems have mentioned yet another kind of constant expression: address constants. The address of an object with static storage duration is an address constant, hence you can do this kind of thing at file scope:
String literals define arrays with static storage duration, so this rule is also why you can do this at file scope:
Another fun little wrinkle: in C, the value of an 'enum' is a constant, but may only be used after the declaration of the 'enum' is complete. The following, for example, is not acceptable in standard C, though it is acceptable in C++:
It could be rewritten:
though this would end up defining multiple different enumeration types, rather than one which holds all the values.
There is another subtlety to constant expressions. There are some things that are known to the compiler, but cannot be known to the preprocessor.
For example
(24*60*60)
can be computed by both, butsizeof struct foo
is only known to the compiler. This distinction can matter if you are trying to verify that astruct
is defined to meet an externally mandated size, or that its members are mapped at externally specified offsets. (This use case often arises when coding device drivers where thestruct
describes device registers as layed out in memory space.)In that instance you cannot simply say
#if (sizeof(struct UART) == 12)
because the preprocessor operates at a pass ahead of the compilation and simply cannot know the size of any types. It is, however, a constant expression and would be valid as an initializer for a global variable (e.g.int UARTwords = sizeof(struct UART) / sizeof(short);
), or to declare the size of an array (e.g.unsigned char UARTmirror[sizeof(struct UART)];
)A constant expression can be evaluated at compile time. That means it has no variables in it. For example:
is a constant expression. Something like:
is not, assuming
someNumber
is a variable (ie, not itself a compile-time constant).Also
integral character constants
as'a'
or'\n'
are constants that the compiler recognizes as such. They have typeint
.Any single-valued literal is a constant expression.
(String literals are weird, because they're actually arrays. Seems
"hello"
isn't really a constant, as it ends up having to be linked and all that, and the address and contents can change at runtime.)Most operators (sizeof, casts, etc) applied to constants or types are constant expressions.
Any expression involving only constant expressions is itself also a constant expression.
Any expression involving function calls or non-constant expressions is usually not a constant expression.
Any macro's status as a constant expression depends on what it expands to.
I originally had some stuff in here about
const
identifiers, but i tested that and apparently it doesn't apply in C.const
, oddly enough, doesn't declare constants (at least, not ones "constant" enough to be used inswitch
statements). In C++, however, it does.