自动化和范围的C ++初始化

时间:2012-03-19 20:37:39

标签: c++ initialization scope

有人能指出我在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;
}

3 个答案:

答案 0 :(得分:2)

由于sequence points的存在,您可以放心地假设p = bar()将在char * q(p)之前发生。

我现在无法通过C ++标准来解决这个问题,但我可以给你相同的C99标准,我希望能让你放心:

<强> 5.1.2.3:

  

访问易失性对象,修改对象,修改文件或调用函数   那些操作中的任何一个都是副作用,这些都是状态的变化   执行环境。表达的评估可能产生副作用。在   执行序列中的某些指定点称为序列点,所有副作用   以前的评估应是完整的,没有后续评估的副作用   应该发生。

附件C: (强调我的)

  

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

     
      
  • 电话   在评估参数之后的函数。
  •   
  • 以下运算符的第一个操作数的结尾:逻辑AND   &&;逻辑OR ||;条件?;逗号,
  •   
  • 完整声明者的结尾;
  •   
  • 的   完整表达式结束:初始化程序;表达在一个   表达陈述; a的控制表达   选择陈述(ifswitch);控制表达   whiledo声明; 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)的变量。块中声明的具有自动存储持续时间的变量在从块

退出时被销毁