Столкнулся с аномалией. В нижеприведенном коде пытаюсь получить МАС из arp таблицы. Для воспроизведения надо поставить в строке 50
cout << resolve_mac("192.168.1.1") << endl;
адрес устройства, видимого в вашей локальной сети и чтобы он был виден в вашей arp таблице (arp -n).
компилирую без ошибок и варнингов
$ g++ bug.cpp --std=c++0x -Wall -Wextra
пустой вывод, видимо возвращается NULL
$ ./a.out
$
Раскомментируем простой cout в строке 36
cout << "> " << ip << endl;
и код работает как надо, тоесть функция возвращает МАС как и задумывалось.
$ ./a.out > 192.168.1.1
00:01:02:03:04:05
Я создал багрепорт http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57937, там мне ответили что дело в возвращении адреса локальной переменной.
Но! Я не могу понять, как влияет простой cout на возвращение или не возвращение адреса локальной переменной ? При чем тут вообще cout?
Может влиять, я помню как пришлось использовать кривое апи, которое тоже возвращало локальную переменную .
Так вод любой код после вызова апи мог убить возвращаемое значение!
Здравствуйте, lnkuser, Вы писали:
L>Я создал багрепорт http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57937, там мне ответили что дело в возвращении адреса локальной переменной. L>Но! Я не могу понять, как влияет простой cout на возвращение или не возвращение адреса локальной переменной ? При чем тут вообще cout?
При том, что локальная переменная находится в области слева от указателя стека, которая может затираться любыми последующими действиями. С момента выхода из функции, вернувшей это, там для компилятора свободная область, которую он может использовать любым образом.
Другие операции с cout или любой другой переменной, любые другие действия меняют распределение использования этой области, и затирание значения может или наступать, или нет, в зависимости от массы факторов.
То, как вы написали — это классическое "неопределённое поведение" (UB — undefined behavior) и не разрешается к использованию.
Для такой простой функции можете объявить буфер, в котором отдаётся значение, как static. Он будет затираться при последующих вызовах, но если это вас устраивает, то нет проблем.
Для более рекомендованных сейчас стилей делается strdup() внутреннего буфера (с free() у вызывающего) или выделение буфера вызывающим.
Здравствуйте, netch80, Вы писали:
N>Для такой простой функции можете объявить буфер, в котором отдаётся значение, как static. Он будет затираться при последующих вызовах, но если это вас устраивает, то нет проблем. N>Для более рекомендованных сейчас стилей делается strdup() внутреннего буфера (с free() у вызывающего) или выделение буфера вызывающим.
Это ж плюсы (хоть и большая часть кода C-style), можно std::string использовать.
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Здравствуйте, lnkuser, Вы писали:
L>Я создал багрепорт http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57937, там мне ответили что дело в возвращении адреса локальной переменной. L>Но! Я не могу понять, как влияет простой cout на возвращение или не возвращение адреса локальной переменной ? При чем тут вообще cout?
При неопределённом поведении, которое происходит из-за возврата локальной переменной, на результат выполнения может повлиять что угодно. На то оно и неопределённое поведение.
Здравствуйте, lnkuser, Вы писали:
L>Я создал багрепорт http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57937, там мне ответили что дело в возвращении адреса локальной переменной. L>Но! Я не могу понять, как влияет простой cout на возвращение или не возвращение адреса локальной переменной ? При чем тут вообще cout?
Я не могу понять, как можно иметь достаточно энергии, чтобы создать багрепорт на gcc, прим этом совершенно не понимая базовых принципов языка?
Нельзя возвращать адрес локальной переменной из функции, поскольку как только функция закончит свою работу, life-time переменной закончится и этот указатель будет
указывать на несуществующий объект.
В подобных случаях можно использовать класс вместо функции.