这是C下的未定义行为吗?我这样说是因为我认为该函数inc(int *k)可以被认为是一个表达式,其副作用是更新地址的值k.那么,这会使它等同于i=i++UB吗?
#include <stdio.h>
/*Edited(See comments below on dbush's answer)*/
int inc(int *k) {return ++(*k);}
/*End of edit*/
int main()
{
int i=0;
int *ptr = &i;
i = inc(ptr);
printf("%d\n", i);
}
Run Code Online (Sandbox Code Playgroud) 有人可以帮我弄清楚这个声明吗?
int *x()(int)
void (*signal(int, void (*fp)(int)))(int)
Run Code Online (Sandbox Code Playgroud)
我似乎无法使用此处给出的方法解析这些。我知道有什么用这种手段cdecl.org并且也是第一个1是非法的,但我想弄清楚如何分析这些?
使用的编译器:gcc 8.2
命令行:-Wall
我目前对序列点违规的理解是代码在某种程度上取决于给定表达式中操作数/子表达式的求值顺序。之所以如此,是因为表达式中操作数的求值顺序未指定,如此处所述。因此,代码如下:
a = 5;
b = a + ++a;
Run Code Online (Sandbox Code Playgroud)
是一种违规并被-Wsequence-point捕获,因为结果存在歧义,即应该是 (5 + 6) 还是 (6 + 6) ?我认为下面的代码中存在类似的歧义,因为我们无法知道第二个 ++a 是否会在第一个之前被评估:
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
int use()
{
int min;
int a = 4, b = 5;
min = MIN(++a, b);
//min = ((++a) < b) ? (++a) : b;
return min;
}
Run Code Online (Sandbox Code Playgroud)
我显然错过了一些东西,因为这段代码没有在-Wseqeuence-point上警告我。有人可以帮我理解什么吗?请注意,我特意按原样定义了 MIN。
在为函数使用 gcc __attribute__ 时,我注意到代码生成存在差异,具体取决于我放置属性的位置。在下面的示例中,我希望编译器不要优化我对 use() 的调用。
编译器:x86-64 gcc(trunk)
选项:-O3 -Wall
void __attribute__((noinline, optimize("O0"))) use() {}
int main ()
{
use();
}
use:
push rbp
mov rbp, rsp
nop
pop rbp
ret
main:
xor eax, eax
call use
xor eax, eax
ret
Run Code Online (Sandbox Code Playgroud)
但是,如果我更改属性的位置,则会生成不同的代码。
void use() {} __attribute__((noinline, optimize("O0")))
int main ()
{
use();
}
main:
push rbp
mov rbp, rsp
mov eax, 0
pop rbp
ret
use:
ret
Run Code Online (Sandbox Code Playgroud)
如果我不放任何属性,我会得到这个:
void use() {}
int main ()
{
use();
}
use:
ret …Run Code Online (Sandbox Code Playgroud)