多重声明中的第二个 int 是否始终设置为 1?
Is the second int in a multiple declaration always set to 1?
在 this Code Golf post 中,声明“定义中的第二个变量总是设置为 1”,因此这是一个格式正确的行:
int i=-1,c,o,w,b,e=b=w=o=c;
并且假设除 i
之外的所有内容都设置为 1,因为 c
自动为 1。
我以为我知道一些 C,并认为这是非法的(作为 UB 并且在随机堆栈内容中产生任何东西)。
C真的把c
设置为1了吗?
此代码显示 undefined behavior。
变量c
、o
、b
和w
未初始化。这意味着它们的内容是不确定的。
来自 C standard 的第 6.7.9 节:
10 If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate.
c
的不确定值然后分配给其他几个变量。通过读取未初始化变量的值,代码会调用未定义的行为。
c
的初始值可能为 1,但如果是,则不是可预测的值。
另请注意,上述语句同时包含初始化(对于i
和e
)和赋值(对于c
、o
、b
、和 w
),因此该语句不会在文件范围内编译。
我试图 运行 链接 post 中的函数,但它没有通过第一个测试输入。未定义的行为。
C 标准中没有这样神奇的规则,第二个 int
对象要设置为 1
。事实上,该值是不确定的,在这种情况下,代码会调用无条件 UB。
C11 § 6.3.2.1/2 左值、数组和函数指示符
If the lvalue designates an object of automatic storage duration that
could have been declared with the register
storage class (never had
its address taken), and that object is uninitialized (not declared
with an initializer and no assignment to it has been performed prior
to use), the behavior is undefined.
但让我们暂时假设不是这样。这只是一个示例程序集,为 GCC 6.3 上的 x86-64 架构生成,turned-off 优化,SysV ABI 调用约定:
mov DWORD PTR [rbp-4], -1
mov eax, DWORD PTR [rbp-8] ; ???
mov DWORD PTR [rbp-12], eax
mov eax, DWORD PTR [rbp-12]
mov DWORD PTR [rbp-16], eax
mov eax, DWORD PTR [rbp-16]
mov DWORD PTR [rbp-20], eax
mov eax, DWORD PTR [rbp-20]
mov DWORD PTR [rbp-24], eax
就编译器而言,没有任何保证。变量 c
位于当前堆栈帧上的 RBP-8
偏移处。它的初始值是任何之前保存在堆栈中的值。
我是 CodeGolf 的 OP。看来我只是打错了,我的意思是
int i=-1,c,o,w,b,e=b=w=o=c=1;
这样第二个定义的 int 总是设置为 1,其他的可以设置为它。令人困惑的是,我最初将下一个 (L=3) 变量设置为 l (undefined),而我将所有其他变量设置为 e=b=w=o=c=(L=3);在我看来,这会将 L 设置为 3,return 对那个 (1) 为真,然后将其余设置为 1。
几次测试后我意识到这只是将它们全部设置为 3,并且只使用我用来测试我的代码的特定字符串。所以我删除了它们并将其更改为 L=3 硬编码,其他的为 e=b=w=o=c=1;L=3
。在某些时候,我一定是按了太多次 cmd+z 并删除了“=”和“1”,所以我只剩下 e=b=w=o=c;
。由于此一贯的未定义性质(至少在我的 IDE 上),它总是将它们定义为 0,因此错误变为 un-noticed。
现在我已经更正了它,多亏了这个 post,字节长度是相同的,而且无论如何都不需要任何这种棘手的 e=b=w=o=c=1
代码,我只是想字节长度不同,因为当我将我的函数复制粘贴到字节计数器时,它显示它小了 2 个字节(我不知道我只是打错了字,少了 2 个字节)。
我的 IDE 总是将这些变量定义为 0。我的代码旨在处理所有定义为 1 的变量,事实上它与 0 一起工作是巧合。也仅仅因为它发生在我的 IDE 上并不意味着它会发生在其他人身上,尽管我已经在现在在线的几个 IDE 上和 运行 很多循环上进行了测试,它似乎确实always return 0. 无论如何,我仍然更新了我的原始代码以将它们设置为 1,因为它应该是(向我的程序添加 2 个字节)。
感谢大家的意见
在 this Code Golf post 中,声明“定义中的第二个变量总是设置为 1”,因此这是一个格式正确的行:
int i=-1,c,o,w,b,e=b=w=o=c;
并且假设除 i
之外的所有内容都设置为 1,因为 c
自动为 1。
我以为我知道一些 C,并认为这是非法的(作为 UB 并且在随机堆栈内容中产生任何东西)。
C真的把c
设置为1了吗?
此代码显示 undefined behavior。
变量c
、o
、b
和w
未初始化。这意味着它们的内容是不确定的。
来自 C standard 的第 6.7.9 节:
10 If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate.
c
的不确定值然后分配给其他几个变量。通过读取未初始化变量的值,代码会调用未定义的行为。
c
的初始值可能为 1,但如果是,则不是可预测的值。
另请注意,上述语句同时包含初始化(对于i
和e
)和赋值(对于c
、o
、b
、和 w
),因此该语句不会在文件范围内编译。
我试图 运行 链接 post 中的函数,但它没有通过第一个测试输入。未定义的行为。
C 标准中没有这样神奇的规则,第二个 int
对象要设置为 1
。事实上,该值是不确定的,在这种情况下,代码会调用无条件 UB。
C11 § 6.3.2.1/2 左值、数组和函数指示符
If the lvalue designates an object of automatic storage duration that could have been declared with the
register
storage class (never had its address taken), and that object is uninitialized (not declared with an initializer and no assignment to it has been performed prior to use), the behavior is undefined.
但让我们暂时假设不是这样。这只是一个示例程序集,为 GCC 6.3 上的 x86-64 架构生成,turned-off 优化,SysV ABI 调用约定:
mov DWORD PTR [rbp-4], -1
mov eax, DWORD PTR [rbp-8] ; ???
mov DWORD PTR [rbp-12], eax
mov eax, DWORD PTR [rbp-12]
mov DWORD PTR [rbp-16], eax
mov eax, DWORD PTR [rbp-16]
mov DWORD PTR [rbp-20], eax
mov eax, DWORD PTR [rbp-20]
mov DWORD PTR [rbp-24], eax
就编译器而言,没有任何保证。变量 c
位于当前堆栈帧上的 RBP-8
偏移处。它的初始值是任何之前保存在堆栈中的值。
我是 CodeGolf 的 OP。看来我只是打错了,我的意思是
int i=-1,c,o,w,b,e=b=w=o=c=1;
这样第二个定义的 int 总是设置为 1,其他的可以设置为它。令人困惑的是,我最初将下一个 (L=3) 变量设置为 l (undefined),而我将所有其他变量设置为 e=b=w=o=c=(L=3);在我看来,这会将 L 设置为 3,return 对那个 (1) 为真,然后将其余设置为 1。
几次测试后我意识到这只是将它们全部设置为 3,并且只使用我用来测试我的代码的特定字符串。所以我删除了它们并将其更改为 L=3 硬编码,其他的为 e=b=w=o=c=1;L=3
。在某些时候,我一定是按了太多次 cmd+z 并删除了“=”和“1”,所以我只剩下 e=b=w=o=c;
。由于此一贯的未定义性质(至少在我的 IDE 上),它总是将它们定义为 0,因此错误变为 un-noticed。
现在我已经更正了它,多亏了这个 post,字节长度是相同的,而且无论如何都不需要任何这种棘手的 e=b=w=o=c=1
代码,我只是想字节长度不同,因为当我将我的函数复制粘贴到字节计数器时,它显示它小了 2 个字节(我不知道我只是打错了字,少了 2 个字节)。
我的 IDE 总是将这些变量定义为 0。我的代码旨在处理所有定义为 1 的变量,事实上它与 0 一起工作是巧合。也仅仅因为它发生在我的 IDE 上并不意味着它会发生在其他人身上,尽管我已经在现在在线的几个 IDE 上和 运行 很多循环上进行了测试,它似乎确实always return 0. 无论如何,我仍然更新了我的原始代码以将它们设置为 1,因为它应该是(向我的程序添加 2 个字节)。
感谢大家的意见