【问题标题】:Is "const int x = get();" legal in C?Can we assign a function's return value to a constant at declaration?是“const int x = get();”在 C 中合法吗?我们可以在声明时将函数的返回值分配给常量吗?
【发布时间】:2013-04-26 11:10:46
【问题描述】:

此论坛上一位知名贡献者"R.." 两天前明确告诉我:

Initializers for objects of static storage duration must be constant expressions. The result of a function call is not a constant expression.

他在谈论全局变量。但我不确定在 main() 函数中声明的常量或与此相关的任何函数是什么。尽管直觉上我觉得即使在函数中声明的常量也是如此,以下来自以下链接的程序,其据称是 correct 答案,让我感到困惑。

http://www.indiabix.com/c-programming/const/discussion-546

#include<stdio.h>
int get();

int main()
{
    const int x = get();
    printf("%d", x);
    return 0;
}

int get()
{
    return 20;
}

那么任何人都可以解释在 C 中将返回值分配给常量是否有效?

【问题讨论】:

  • ... 和 IIRC,我两天前告诉过你,C 中没有 global variables 这样的东西,你指的是在文件范围内声明的变量具有静态存储持续时间。有相当大的差异。在文件范围内声明的变量的可见性要低得多;它们在它们自己的翻译单元中可见,它们的声明之后。全局变量在它们的翻译单元之外,在它们声明之前也是可见的。
  • @undefinedbehaviour 您在什么情况下发表了此评论?您是否R.. 使用另一个ID?谁是IIRC?顺便说一句,C 中真的没有全局变量吗?所有函数外声明的变量不是全局变量吗?
  • 在“C 中的全局变量”的上下文中,由于我上面指出的原因不存在,我提到它们不存在。我不是 R.. IIRC 代表“如果我没记错的话”。如果您愿意,您可以在 C 标准中搜索“global”,它不会找到任何相关内容。正如我之前所说,在所有函数之外声明的变量在文件范围声明,具有静态存储持续时间,并且它们仅从声明点到声明点可见翻译单元的结尾。这与其他语言中对全局变量的定义不同。
  • @undefinedbehaviour 我已经把它作为一个硬性的 N 快速规则钻进我的脑海中,即函数外的变量在 C 中称为“全局变量”。你能给出一个严格的定义吗?我在什么中称这些变量那么C呢?
  • @undefinedbehaviour 甚至一些关于 C 的书籍和流行网站也使用该术语。

标签: c constants


【解决方案1】:

是的,它完全有效,因为您的变量是自动的,即 不是 static

这些限制适用于static 变量,其值必须在编译时已知。

请注意,C 区分“常量表达式”和其他表达式,并且用于static 变量的初始化值必须是这样的常量表达式。对于非static变量,则没有这个要求。

【讨论】:

  • 如果您能分享更多关于此的事实,这将非常有帮助。请详细说明,除非这个问题是重复的。我相信许多其他新手很想了解更多有关它的信息。跨度>
  • 在与 C 一样具有许多未定义和实现定义行为的语言中,“试一试”几乎从来都不是对“这合法吗?”问题的有用回答。
  • @Cairnarvon 太好了,好像我已经不感到困惑了,现在我看到有 123k 声望的人被否决了。Cairnarvon 请在答案中发布,我相信很多像我这样的人会受益.
  • @Cairnarvon 公平点,虽然“试试看”的建议在这里很常见,但它确实给实现留下了太多的负担。我重新写了,谢谢。
  • @SheerFish Downvoting 我很好,这让我变得更好!代表很好,但并不神奇。
【解决方案2】:

是的,这个赋值是有效的 C。但是 x 不是一个常量表达式,它是一个 const 限定的变量,这不是一回事(至少在 C 中)。

C11 (n1570),第 6.6 节常量表达式

一个整数常量表达式应该是整数类型并且应该只有操作数 即整数常量、枚举常量、字符常量、sizeof 结果是整数常量、_Alignof 表达式和浮点数的表达式 作为强制类型转换的直接操作数的常量。

整数常量类似于420L89.0。例如,在下面的代码 sn-p 中,2 是整数常量,但 x 不是。

const int x = 2;

【讨论】:

  • 如果您能详细说明一下上下文中的 const 限定变量和常量表达式之间的区别,将会非常有帮助。谢谢
  • 虽然我必须承认你的avatar-photo 让我分心了一段时间。我们在这个论坛上看不到那么多,在如此高的声誉旁边也很少看到
  • 来自法国的Mademoiselle,请在这方面详细说明const-qualified variable vs const-qualified variable。Plz
  • @undefinedbehaviour trap representations是什么?请告诉
  • @SheerFish 这不是用户 Kirilenko 的照片,而是 the Tennis player,我们的 Kirilenko 显然是他的粉丝。
【解决方案3】:

我认为让您感到困惑的是,您将 类型限定符 const存储类说明符 static 混淆了。这些是完全不同的功能,您无法相互比较。

const 表示一个变量在其声明的作用域内是只读的,只有在初始化时才能赋值。也就是说,在定义 const 变量的同一行上。没有别的意思。

静态存储持续时间意味着变量将存在于程序的整个执行过程中。所有声明为static 的变量和所有在文件范围内声明的变量(“全局变量”)都具有静态存储持续时间。如前所述,具有静态存储持续时间的变量只能使用 常量表达式 进行初始化,不要与声明为 const 的只读变量混淆。

那么任何人都可以解释在 C 中将返回值分配给常量是否有效?

视情况而定。

  • 在文件范围内声明的任何变量都具有静态存储持续时间。
  • 必须使用常量表达式初始化具有静态存储持续时间的变量。
  • 函数的返回值不是常量表达式。
  • 因此,具有静态存储持续时间的变量无法使用函数的返回值进行初始化。

如您所见,这与 const 关键字无关,而是与声明变量的位置有关。如果变量 const 是否在本地范围内声明,则可以使用任何值对其进行初始化,如您的代码示例所示。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-29
    • 2011-05-22
    • 2021-12-18
    • 1970-01-01
    相关资源
    最近更新 更多