在C99程序中可以出现`const`限定类型

时间:2017-11-06 23:55:00

标签: c c99

TL; DR 哪些const可以出现在C99程序中而不被忽略?或者相反:在C99程序中const添加非平凡约束的位置?

我的理解是const限定符仅适用于允许限定类型的少数几个地方。 “有用”在这里用于语义,意思是“添加非平凡约束”。我const有用的地方列表包括:

  • 附加到指针和数组类型,以描述指向/元素类型的可变性。例如。 int const *
  • 描述某些变量声明的可变性(作为函数参数或局部变量)。例如。 int const x = 1
  • 描述了struct / union中某些字段的可变性。例如。 struct Foo { int baz; int const quux; }
  • typedef中,当在上述案例之一中使用
  • ???

我很难找到这些详尽的清单。我已经略过了C99规范,但这几乎不是轻读。 :)

非常感谢!

修改

以下是AFAICT const不“有用”的一些案例:

  • 任何返回值(rvalues不能变异)。例如。 const int foo() { return 2; }
  • 任何演职员(仍然是左撇子......)。例如。 (int const) bar()
  • sizeof(限定/非限定类型的对齐和大小相同)。例如。 sizeof(const int)

1 个答案:

答案 0 :(得分:3)

根据语言语法 type-qualifier 可以作为 type-name 的一部分出现。如果您查看 type-name 的语言语法,您将找到可以使用它的所有上下文。那将是:声明,演员表,复合文字,泛型,sizeof_Atomic_Alignas_Alignof

  • 可以肯定地说,在过去四年的背景下 - sizeof_Atomic_Alignas_Alignof - const在任何间接层面都没有区别。

  • _Generic似乎仍然没有明确规定,但可以安全地假设顶级const没有任何区别。更深层次的间接const问题在_Generic

  • 至于其他人,管理规则是:顶级const仅对 lvalues 有意义。应用于 rvalues 时没有任何区别。这意味着将顶级const限定应用于函数返回类型或转换中的目标类型没有意义。

    在更深层次的间接使用的限定词显然很重要。

    请注意,复合文字是左值,意味着复合文字中的顶级const很重要

    int *p = (const struct { int a[10]; }) { 0 }.a; // Error: discards `const`
    
  • 还有一些奇怪的例子,例如

    const struct S { int a[10]; } foo(void)
    {
      return (struct S) { 0 };
    }
    
    int main()
    {
      int *p = foo().a;
    }
    

    它在GCC中编译,但是,如果我没有弄错的话,无论如何行为都是未定义的。