3

我想专门为某个 GUID 设计一个模板,它是一个 16 字节的结构。GUID 对象有内部链接,所以我不能使用对象本身的地址,但我认为我可以使用对象的内容,因为对象是一个常量。但这不起作用,如此示例代码所示:

struct S
{
    int const i;
};
S const s = { 42 };
char arr[s.i];

如果 s 是常数,为什么 si 不是常数?任何解决方法?

4

2 回答 2

7

结构的初始化s可以在运行时发生。但是,数组的大小必须在编译时知道。编译器不会(肯定)知道 的值s.i在编译时是已知的,所以它只是看到你正在使用一个你不应该使用的变量。问题不在于常量,而是何时需要数组大小的问题。

你可能误解了什么const意思。这只意味着变量初始化后,永远不会改变。例如这是合法的:

void func(int x){
    const int i = x*5; //can't be known at compile-time, but still const
    //int array[i]; //<-- this would be illegal even though i is const 
}

int main(){
    int i;
    std::cin >> i;
    func(i);
    return 0;
}

为了绕过这个限制,在 C++11 中,您可以将其标记为constexpr指示该值可以在编译时确定。这似乎是你想要的。

struct S
{
    int const i;
};
int main(){
    constexpr S const s = { 42 };
    char arr[s.i];
    return 0;
}

编译:

$ c++ -std=c++11 -pedantic file.cpp


在 C99 中,您所做的是合法的,数组的大小不需要在编译时知道。

struct S
{
    int const i;
};
int main(){
    struct S const s = { 42 };
    char arr[s.i];
    return 0;
}

编译:

$ cc -std=c99 -pedantic file.c

于 2013-03-13T17:47:06.540 回答
2

至少在大多数情况下,const实际上意味着更接近“只读”而不是“常量”。在 C89/90 中,它基本上意味着“只读”。C++ 增加了一些它可以保持不变的情况,但它仍然没有接近所有时间(不幸的是,在不平凡的情况下准确跟踪它的含义)。

幸运的是,“解决方法”是以几乎可以肯定在任何情况下都应该的方式编写代码:

std::vector<char> arr(s.i);

底线:C++ 中内置数组的大多数使用都应该被认为是可疑的。您可以从非常量表达式初始化向量这一事实只是众多优势之一。

于 2013-03-13T17:52:29.750 回答