C ++对静态const积分类型有什么特殊规则?

时间:2012-12-18 15:37:50

标签: c++ static const standards

我认为C ++会将相同的特殊规则应用于static const整数类型 ,无论 是否在命名空间范围内声明或声明在类/结构/联合中。

现在我想我已经被不合规的编译器教给了Bad Things。

static const int A = 1;

struct s
{
    static const int A = 1;
};

除了范围明显不同之外,As::A的区别如何?

  • ...当他们的用法被替换为他们的字面值?
  • ......什么时候可以拿到它的地址?
  • ...当我需要单独定义它们时?

我特别好奇C ++ 03。

2 个答案:

答案 0 :(得分:6)

关键字static在类范围内并不意味着相同 并在命名空间范围内。实际上,它在命名空间范围内的用途是 弃用。

在类范围内声明变量时,static表示 将有一个变量的单个实例,带有static 储存期限和寿命。课堂上的宣言 不是定义;如果变量使用,则必须是 在一个(只有一个)翻译单元中定义;如果不是 定义,你有未定义的行为。 (在实践中,取决于 在使用上,要么一切都会正常,否则你会得到一个 来自链接器的错误。)注意,如果声明是为了 一个const整数类型,并包含一个初始化,它是 not 如果在需要的上下文中使用,则被视为已使用 一个常量积分表达式(如C风格的维度) 数组)。最简单和最可靠的事情就是定义它 某处。

在命名空间范围内声明变量时,static表示 名称有内部联系,而不是外部;同 或者没有static,声明是一个定义(所以那里 程序中应该没有其他定义)。在C ++ 03中,这个 使用已被弃用;请改用未命名的命名空间。请注意 如果变量本身是const(顶级const),那么 它默认具有内部链接,因此static没有 任何影响。 (如果您需要const变量 外部链接,使其成为类成员或定义它 明确extern,使用初始化程序来实现它 定义,而不仅仅是声明。)

答案 1 :(得分:0)

  

As::A有何不同?

最大的区别是A的声明也是一个定义,而s::A的声明则不然。我不确定你的“特殊规则”是什么意思,但static在每种情况下都有不同的含义。

在命名空间范围内,它为其提供内部链接,以便在当前翻译单元外部看不到该对象。请注意,static在这里是多余的,因为命名空间范围内的常量变量默认具有内部链接。

在类范围内,这意味着只有一个对象独立于类的任何实例化。

  

当他们的用法被替换为他们的字面值?

由于两者都是声明中具有初始化的整数常量,因此两者都可以在常量表达式中使用,并且编译器能够用编译时常量替换它们的值。

或许更合适的问题是,何时需要定义?

在C ++ 11中,如果变量是 odr-used 则需要它 - 粗略地说,如果你做任何需要变量的地址而不是它的值的东西。

在C ++ 03中,我认为如果完全使用该变量则需要它,虽然不需要诊断,如果你只使用它的值,许多编译器都不会抱怨。我可能错了;旧的规则相当复杂,我很高兴现在能够忘记它们。

  

什么时候可以拿到它的地址?

这要求变量在C ++ 03和C ++ 11中都有定义。该定义为变量分配存储空间,以便它具有地址。

  

当我需要单独定义它们时?

命名空间范围内的变量声明也是一个定义,除非您声明它extern;所以你的第一个变量不需要单独的定义。

类范围内的变量声明不是定义;所以你的第二个变量在C ++ 03中需要一个单独的定义,如果它是 odr-used ,则在C ++ 11中需要。

相关问题