C ++ инициализация автоматики и области видимости - PullRequest
1 голос
/ 20 марта 2012

Может кто-нибудь указать мне ссылку в стандарте C ++, которая гарантирует, что автоматическое char * q в функции foo1 () всегда будетинициализируется после вызова p = bar () в foo1 () .Я так привык к созданию нового блока, как в foo2 () , и мне интересно, слишком ли я тупой и параноидальный оптимизирующий компилятор.Или я прав, будучи параноиком, и не должен предполагать, что компилятор не будет оптимизировать код так, чтобы p = bar () всегда вызывался до q (p) ?Спасибо!

#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 ]

2 голосов
/ 20 марта 2012

Можно смело предположить, что p = bar() произойдет раньше char * q(p) из-за существования точек последовательности .

Я не могу сейчас пробиться через стандарт C ++, но могу дать вам эквивалент из стандарта C99, который, я надеюсь, достаточно успокоит вас:

5.1.2.3:

Доступ к изменчивому объекту, изменение объекта, изменение файла или вызов функции что любая из этих операций все побочные эффекты, которые являются изменениями в состоянии среда исполнения. Оценка выражения может привести к побочным эффектам. В определенные указанные точки в последовательности выполнения, называемые точками последовательности, все побочные эффекты предыдущих оценок должны быть полными и не иметь побочных эффектов последующих оценок должно было иметь место.

Приложение C: (выделено мое)

Ниже приведены точки последовательности, описанные в 5.1.2.3:

.
  • звонок в функцию после оценки аргументов.
  • Конец первого операнда следующих операторов: логическое И &&; логическое ИЛИ ||; условный ?; запятая ,.
  • Конец полного декларатора;
  • The конец полного выражения: инициализатор ; выражение в выражение выражения; контролирующее выражение оператор выбора (if или switch); контролирующее выражение оператора while или do; каждое из выражений for заявление; выражение в выражении return.
  • Непосредственно перед возвратом библиотечной функции.
  • После действия, связанные с каждой отформатированной функцией ввода / вывода спецификатор преобразования.
  • Непосредственно перед и сразу после каждого вызова функции сравнения, а также между любой вызов функции сравнения и любое движение объектов переданы в качестве аргументов для этого вызова.
1 голос
/ 20 марта 2012

Тебе не нужно быть этим параноиком.C ++ говорит:

Каждое вычисление значения и побочный эффект, связанный с полным выражением, секвенируются перед каждым вычислением значения и побочным эффектом, связанным со следующим полным выражением, которое будет оценено.

[intro.execution] 1,9 / 14, n3337

0 голосов
/ 20 марта 2012

C ++ 03 6.7 / 2 «Заявление декларации» гласит:

Переменные с автоматическим хранением (3.7.2) инициализируются каждый раз, когда выполняется их объявление-оператор. Переменные с автоматической продолжительностью хранения, объявленные в блоке, уничтожаются при выходе из блока

...