2010-12-08 4 views
7

Набросился на какой-то код, как это в нашей базе кода ..., что заставило меня волноваться.Возвращаемое значение из локального объема?

int foo(int a); // Forward declaration. 

int baz() { 
    int result = { 
     int a = dosomestuff(); 
     foo(a); 
    } ? 0 : -1; 
    return result; 
} 
  1. хорошо Определена ли поведение этого кода?
  2. Будет ли это действительно работать, что переменная result загружается с 0 или -1 в зависимости от возвращаемого значения foo(a)?

Для интереса: Код был написан не так изначально - тем не менее, это то, что я представляю себе этот невинный вид макрос раскатываются ...

int foo(int a); // Forward declaration. 

#define BAR() { int a = dosomestuff(); foo(a); } 

int baz() { 
    int result = BAR() ? 0 : -1; 
    return result; 
} 
+0

Yow. Что компилятор C принимает? gcc конечно нет. – aschepler 2010-12-08 18:49:21

+1

@aschepler: по иронии судьбы, кажется, что GCC является * единственным * компилятором, который его принимает! См. Ответ Майкла Берра. – 2010-12-08 19:07:24

+0

Компилятор VisualDSP ++ от Analog Devices. Я, вероятно, попрошу об этом завтра. – 2010-12-08 20:49:26

ответ

11

Это расширение GCC на C называется «Заявление выражения»: http://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html

Главное, что выражение оператор возвращает последнее, что он делает, как значение выражения:

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

В вашем примере это будет то, что возвращается foo(a).

Однако блок должен быть заключен в parens для GCC для принятия синтаксиса.

int foo(); // Forward declaration. 

int baz() { 
    int result = ({ 
     int a = dosomestuff(); 
     foo(a); 
    }) ? 0 : -1; 
    return result; 
} 

Я не знаю ни одного другого компилятора, который поддерживает это.

+0

Вы попали туда первым. Как FYI здесь ссылка на все расширения GCC C http://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html#C-Extensions – 2010-12-08 18:58:22

0

Потому что это простой указатель без указателя, то точное значение будет возвращено, и поэтому будет определено поведение возврата. Этот блок ... действительно странный, хотя, и я удивлен, есть компилятор C, который не задушит его там.

1

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

int foo(); 
int dosomestuff(); 

int baz() 
{ 
    int result = foo(dosomestuff()) ? 0 : -1; 
    return result; 
} 
4

Вам нужно будет проконсультироваться со своей документацией к компилятору. Эта конструкция не допускается в стандартном C или стандартном C++.

Это тривиально, чтобы очистить это, однако, например,

int baz() 
{ 
    int result; 
    { 
     int a = dosomestuff(); 
     result = foo(a)? 0: -1; 
    } 
    return result; 
} 
1

Это не стандарт C++.

В стандартном C++, написать

bool baz() { return !foo(dosomestuff()); } 

Вот и все.

0

С C++ 11 вы можете получить довольно близко:

int foo(int a); // Forward declaration. 

int baz() { 
    int result = []{ 
     int a = dosomestuff(); 
     return foo(a); 
    }() ? 0 : -1; 
    return result; 
} 
Смежные вопросы