C++;自动和范围的初始化 可以指点我在C++标准中的一个引用,它保证在PoF1()中调用P= Bar()之后,函数Foe1()中的自动char *Q总是被初始化。我已经习惯于像foo2()中那样创建一个新的块,我想知道我是否对优化编译器过于依赖和偏执。或者我的偏执是正确的,我不应该假设编译器不会优化代码,使得p=bar()总是在q(p)之前被调用? 谢谢 #包括 #包括 #包括 char*bar() { char*t=(char*)malloc(15); strcpy(t,“你好,世界!”); 返回t; } void foo1(void) { char*p=NULL; printf(“foo1:做一些事情\n”); p=巴(); printf(“foo1:做更多的事情\n”); char*q(p); printf(“foo1:q表示:%s\n”,q); 自由基(p); } 无效2(无效) { char*p=NULL; printf(“foo2:做一些事情\n”); p=巴(); printf(“foo2:做更多的事情\n”); //这个街区有必要吗? { char*q(p); printf(“foo2:q表示:%s\n”,q); } 自由基(p); } int main(int ac,char*av[]) { foo1(); foo2(); 返回0; }

C++;自动和范围的初始化 可以指点我在C++标准中的一个引用,它保证在PoF1()中调用P= Bar()之后,函数Foe1()中的自动char *Q总是被初始化。我已经习惯于像foo2()中那样创建一个新的块,我想知道我是否对优化编译器过于依赖和偏执。或者我的偏执是正确的,我不应该假设编译器不会优化代码,使得p=bar()总是在q(p)之前被调用? 谢谢 #包括 #包括 #包括 char*bar() { char*t=(char*)malloc(15); strcpy(t,“你好,世界!”); 返回t; } void foo1(void) { char*p=NULL; printf(“foo1:做一些事情\n”); p=巴(); printf(“foo1:做更多的事情\n”); char*q(p); printf(“foo1:q表示:%s\n”,q); 自由基(p); } 无效2(无效) { char*p=NULL; printf(“foo2:做一些事情\n”); p=巴(); printf(“foo2:做更多的事情\n”); //这个街区有必要吗? { char*q(p); printf(“foo2:q表示:%s\n”,q); } 自由基(p); } int main(int ac,char*av[]) { foo1(); foo2(); 返回0; },c++,initialization,scope,C++,Initialization,Scope,您可以放心地假设,由于存在的原因,p=bar()将出现在char*q(p)之前 我不能让自己现在通过C++标准,但是我可以给你与C99标准的等价物,我希望你能放心地: 5.1.2.3: 访问易失性对象、修改对象、修改文件或调用函数 也就是说,所有这些操作都是副作用,都是机体状态的变化 执行环境。表达式的计算可能会产生副作用。在 执行序列中的某些指定点称为序列点,所有副作用 之前评估的结果应完整,且后续评估无副作用 应该已经发生了 附件C:(重点) 以下是5.1.2.3中描述的序列点: 电话 在

您可以放心地假设,由于存在的原因,
p=bar()
将出现在
char*q(p)
之前

我不能让自己现在通过C++标准,但是我可以给你与C99标准的等价物,我希望你能放心地:

5.1.2.3:

访问易失性对象、修改对象、修改文件或调用函数 也就是说,所有这些操作都是副作用,都是机体状态的变化 执行环境。表达式的计算可能会产生副作用。在 执行序列中的某些指定点称为序列点,所有副作用 之前评估的结果应完整,且后续评估无副作用 应该已经发生了

附件C:(重点)

以下是5.1.2.3中描述的序列点:

  • 电话 在对参数求值后,对函数执行
  • 以下运算符的第一个操作数的结尾:逻辑AND
    &&
    ;逻辑或;有条件的
    ;逗号
  • 完整声明符的结尾
  • 完整表达式的结尾:初始值设定项;英语中的表达 表达陈述;a的控制表达式 选择语句(
    if
    开关
    );控制表达式 当或执行语句时的;对于 陈述
    return
    语句中的表达式
  • 在库函数返回之前
  • 之后 与每个格式化输入/输出函数关联的操作 转换说明符
  • 紧接之前及 每次调用比较函数后,以及 对比较函数的任何调用以及对象的任何移动 作为参数传递给该调用
C++03 6.7/2“声明声明”中说:

具有自动存储持续时间(3.7.2)的变量在每次执行声明语句时初始化。在块中声明了自动存储持续时间的变量在退出块时被销毁


你不必这么偏执。C++表示< /P> 每个值的计算和副作用与 完整表达式在每次值计算和边计算之前排序 与要计算的下一个完整表达式关联的效果

[intro.execution]1.9/14,n3337


哇-你能说“伪装成C++的可怕的C代码”吗?我现在不能指出标准的具体部分,但他们要寻找的关键短语是序列点。@Steve我更喜欢写
char*q=p
char*q(p)
,因此不要与
q
混淆。q是一个函数,它接受
p
类型的参数,并返回一个
char*
@Steve:为了人性起见,请使用
std::string
。没有理由使用代码管理>内存> <代码> > />代码> For()/代码> C++中的所有时间,就像现在一样。马赫什和Times:我深深地为使用C++代码来提出这个问题而道歉。有些C编译器会编译这个,有些不会。到目前为止,我尝试过的所有C++编译器都会。我想不出一个更简单的方法用更少的语言来表达这个问题。感谢您的主题回复。我认为C++11放弃了“sequenced before”和“sequenced after”的序列点。@bames53:确实如此,但只是措辞有所改变——语义与C++03相同,只是措辞更清晰。+1表示正确答案。但你为什么引用N3337。我的意思是,N3290与当前的标准(C++11)相同,而N3337是下一个标准的初稿?@cheerrandhth.-Alf:N3290已经有一段时间没有免费提供了;也许bames根本就没有副本?@Cheersandhth.-Alf n3337是该标准的第一份C++11之后的草案。它包含了已发布的C++11标准的所有内容,但也修复了一些打字错误等。
#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;
}