简体   繁体   English

来自另一个 static 常量变量的 static 常量变量给出编译错误?

[英]static const variable from a another static const variable gives compile error?

Why this compiles:为什么编译:

static const short test_value = 0x0100;
static const uint8_t *is_big_endian = ((const uint8_t *) &test_value);

but this doesn't:但这不是:

static const short test_value = 0x0100;
static const uint8_t is_big_endian = *((const uint8_t *) &test_value);

with the error:出现错误:

expression must have a constant value表达式必须有一个常量值

I made up some false sense about it and tried the following:我对此做了一些错误的理解并尝试了以下方法:

static uint8_t is_big_endian = *((const uint8_t *) &test_value);

Which also didn't compile and produced the same error!哪个也没有编译并产生相同的错误!
I also have tried to play with the location of the const but nothing worked.我也尝试过使用const的位置,但没有任何效果。

I'm using Visual Studio 2019.我正在使用 Visual Studio 2019。

Edit:编辑:
It seems to work in C++ but not C.它似乎适用于 C++ 但不适用于 C。 So now my questions are:所以现在我的问题是:

  1. Why it isn't compiling in C?为什么它不在 C 中编译?
  2. What C++ does different that enables it? C++ 有什么不同可以实现它?

The C standard does not require compilers to figure out the bytes that make up an object while evaluating expressions for initializers. C 标准不要求编译器在评估初始化程序的表达式时找出构成 object 的字节。 So, while *((const uint8_t *) &test_value) might have a logically determined value that you can figure out from knowledge of test_value , the compiler is not required to figure it out.因此,虽然*((const uint8_t *) &test_value)可能有一个逻辑确定的值,您可以从test_value的知识中找出它,但编译器不需要找出它。

C 2018 6.8 7 says a constant expression used in an initializer may be an arithmetic constant expression, a null pointer constant, an address constant, or an address constant plus or minus an integer constant expression. C 2018 6.8 7 表示初始化器中使用的常量表达式可以是算术常量表达式、null 指针常量、地址常量或地址常量加上或减去 Z157DB7DF530023575E8ZD36 表达式。 The expression *((const uint8_t *) &test_value) is not any of the latter three forms, since they are pointers of various kinds.表达式*((const uint8_t *) &test_value)不是后三个 forms 中的任何一个,因为它们是各种类型的指针。 Let's consider the first form, an arithmetic constant expression.让我们考虑第一种形式,算术常量表达式。

C 2018 6.8 8 defines arithmetic constant expression : C 2018 6.8 8 定义算术常数表达式

An arithmetic constant expression shall have arithmetic type and shall only have operands that are integer constants, floating constants, enumeration constants, character constants, sizeof expressions whose results are integer constants, and _Alignof expressions.算术常量表达式应具有算术类型,且操作数应为 integer 常量、浮点常量、枚举常量、字符常量、结果为 integer 常量和_Alignof表达式的sizeof表达式。 Cast operators in an arithmetic constant expression shall only convert arithmetic types to arithmetic types, except as part of an operand to a sizeof or _Alignof operator.算术常量表达式中的强制转换运算符只能将算术类型转换为算术类型,但作为sizeof_Alignof运算符的操作数的一部分除外。

So *((const uint8_t *) &test_value) is not an arithmetic constant expression because it contains a cast of a pointer, not an arithmetic type, and that cast is not part of an operand to sizeof or _Alignof .所以*((const uint8_t *) &test_value)不是算术常量表达式,因为它包含指针的转换,而不是算术类型,并且该转换不是sizeof_Alignof操作数的一部分。 It also contains test_value as an operand, and that is not one of the list permissible kinds of operand.它还包含test_value作为操作数,这不是列表允许的操作数类型之一。 It also contains &test_value as an operand, and that is also not one of the permissible kinds.它还包含&test_value作为操作数,这也不是允许的类型之一。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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