有人能指出我在C ++标准中的参考,它保证函数 foo1()中的自动 char * q 在 foo1()中调用 p = bar()后,将始终初始化。我习惯于在 foo2()中创建一个新的块,并且想知道我是否过度阻止和偏爱优化编译器。或者我是偏执的正确,不应该假设编译器不会优化代码,以便在 q(p)之前始终调用 p = bar()? 谢谢!
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
char* bar()
{
char* t = (char*)malloc(15);
strcpy(t, "Hello World!");
return t;
}
void foo1(void)
{
char* p = NULL;
printf("foo1: do some stuff\n");
p = bar();
printf("foo1: do some more stuff\n");
char* q(p);
printf("foo1: q says:%s\n", q);
free(p);
}
void foo2(void)
{
char* p = NULL;
printf("foo2: do some stuff\n");
p = bar();
printf("foo2: do some more stuff\n");
// is this block necessary?
{
char* q(p);
printf("foo2: q says:%s\n", q);
}
free(p);
}
int main(int ac, char* av[])
{
foo1();
foo2();
return 0;
}
答案 0 :(得分:2)
由于sequence points的存在,您可以放心地假设p = bar()
将在char * q(p)
之前发生。
我现在无法通过C ++标准来解决这个问题,但我可以给你相同的C99标准,我希望能让你放心:
<强> 5.1.2.3:强>
访问易失性对象,修改对象,修改文件或调用函数 那些操作中的任何一个都是副作用,这些都是状态的变化 执行环境。表达的评估可能产生副作用。在 执行序列中的某些指定点称为序列点,所有副作用 以前的评估应是完整的,没有后续评估的副作用 应该发生。
附件C: (强调我的)
以下是5.1.2.3中描述的序列点:
- 电话 在评估参数之后的函数。
- 以下运算符的第一个操作数的结尾:逻辑AND
&&
;逻辑OR||
;条件?
;逗号,
。- 完整声明者的结尾;
- 的 完整表达式结束:初始化程序;表达在一个 表达陈述; a的控制表达 选择陈述(
if
或switch
);控制表达while
或do
声明;for
的每个表达式 声明;return
语句中的表达式。- 紧接库函数返回之前。
- 之后 与每个格式化输入/输出功能相关的动作 转换说明符。
- 之前和之前 每次调用比较函数后立即执行 对比较函数的任何调用以及对象的任何移动 作为该调用的参数传递。
答案 1 :(得分:1)
你不需要成为这种偏执狂。 C ++说
与a相关的每个值计算和副作用 full-expression在每个值计算和side之前排序 与要评估的下一个完整表达相关联的效果。
[intro.execution] 1.9 / 14,n3337
答案 2 :(得分:0)
C ++ 03 6.7 / 2“声明声明”说:
每次执行声明语句时,都会初始化具有自动存储持续时间(3.7.2)的变量。块中声明的具有自动存储持续时间的变量在从块
退出时被销毁