Условный оператор, чай баг - мой или gcc ?
От: ScorpZ Украина  
Дата: 28.05.13 09:06
Оценка: 2 (1)
1  #include <iostream>
2  #include <functional>
3
4  typedef std::function<void (int)> ffPtrT;
5
6  void f1(int i) {}
7
8  void call(ffPtrT fPtr)
9  {
10   if(fPtr != nullptr)
11   {
12     std::cout << ">>> TRUE !!!" << std::endl;
13     fPtr(10);                    // Sigfault here
14   }
15   else
16   {
17     std::cout << ">>> FALSE !!!" << std::endl;
18   }
19 }
20
21 int main(int argc, char** argv)
22 {
23   bool setCall = false;
24   call((setCall ? &f1 : nullptr));
25 }

//------------------------------------------------------- Console
./test_c
>>> TRUE !!!
Segmentation fault (core dumped)
//------------------------------------------------------- Console

Всем привет.
Столкнулся с таким загадочным поведением gcc.
Вообщем есть такая программка, скомпиленая на gcc 4.7.2 с поддержкой 11 стандарта и некоторыми его фичами (std::function).
Если следовать логике, то в тирнарном операторе должен вычислятся правый операнд (nullptr) и он же должен передаваться в call(),
где значение nullptr используется для инициализации fPtr. По факту — в fPtr попадаетя какой то мусор, который совсем не равен nullptr.

Да, и еще — gcc, при компиляции, не выдает никаких ошибок или ворнингов.

В итоге починилоь все таким образом —
24   call((setCall ? ffPtrT(&f1) : ffPtrT(nullptr)));  
// на самом деле все работает даже если только для 2го операнда создавать временный указатель
// то есть

24   call((setCall ? ffPtrT(&f1) : nullptr));

//------------------------------------------------------- Console
./test_c
>>> FALSE !!!
//------------------------------------------------------- Console

А теперь вопрос знатокам С++ — что это было ?
добавлена разметка
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.