2015-01-14 1 views
2

я наткнулся на некоторый код сегодня, я упростил его к этому:Попутный неинициализированная безопасности

#include <iostream> 
using std::cout; 
using std::cin; 

bool changeX(int &x) 
{ 
    x = 5; 
    return true; 
} 

void printvals(bool bval, int intval) 
{ 
    cout << bval << " : " << intval; 
} 

int main() 
{ 
    int x; 
    printvals(changeX(x), x); 
    cin.get(); 
} 

Здесь x еще инициализирован в то время он передается функции printvals, но я могу с уверенностью сказать, что х будет всегда быть инициализированным до того, как его использует печать? Я попытался запустить мой упрощенный код в режиме отладки VS2013, который дал мне: Run-Time Check Failure #3 - The variable 'x' is being used without being initialized.. Тем не менее, запуск его в режиме release прошел нормально и печатался: 1 : 5 как и ожидалось.

Означает ли это, что я могу использовать этот подход в производственном коде? Будет ли x всегда инициализироваться до того, как printvals может использовать его, чтобы он не вызывал UB?

+0

Возможный дубликат [Компиляторы и порядок оценки аргументов в C++] (http://stackoverflow.com/questions/621542/compilers-and-argument-order-of-evaluation-in-c) – CoryKramer

ответ

9

Могу ли я сказать, что x всегда будет инициализирован до использования printvals?

Нет, порядок оценки параметров функции не указан. Поскольку вы можете читать из неинициализированной переменной, ваш код может иметь неопределенное поведение. Вы не можете полагаться на побочные эффекты вызова на changeX.

4

Порядок оценки аргументов в функции неуказанный, так что НЕТ, вы не можете этого сказать.

См., Например, http://en.cppreference.com/w/cpp/language/eval_order

или увидеть стандарт, если вы решитесь прочитать «standardese» :)

PS: даже если, возможно, был указан порядок, это всегда хорошая идея, чтобы избежать подобного кода, так как большую часть времени другие люди, читающие ваш код, будут иметь точно такой же вопрос и будут терять много времени, чтобы копаться. Просто предпочитайте ясность над чрезвычайно «умным» кодом.

+0

Хех, стандартное здесь очень просто, см. [мой ответ] (http://stackoverflow.com/a/27947714/2069064). На самом деле почти дословно ваше первое предложение :) – Barry

+0

@ Барри, действительно, наконец, кусок простого английского;) – vsoftco

1

Это может привести к неопределенному поведению, поскольку порядок выполнения не указан (это зависит от компилятора).

1

Это одно из тех мест, где стандарт C++ чрезвычайно прост для понимания. Из §8.3.6/9 (в N3797, курсив мой):

Порядок вычисления аргументов функции является неопределенные.

Это означает, что вы не можете полагаться на intval оценивается как копия xпослеchangeX() называется. Таким образом, ваш код является неопределенным поведением.