Этот вопрос на самом деле состоит из двух наблюдений.
Во-первых: включение <atomic>
приводит к тому, что GCC не выдает диагностику conversion-null
, по крайней мере, в некоторых случаях, когда в противном случае это происходит.
Например, рассмотрим файл noerror.cpp
:
#include <atomic>
#pragma GCC diagnostic error "-Wconversion-null"
int * foo() {return false;}
Этот файл (error.cpp
) идентичен, за исключением закомментированного включения:
//#include <atomic>
#pragma GCC diagnostic error "-Wconversion-null"
int * foo() {return false;}
Если я попытаюсь скомпилировать error.cpp
, я получу ошибку, как и ожидалось:
$ g++-4.8 -c -std=c++11 error.cpp
error.cpp: In function ‘int* foo()’:
error.cpp:3:21: error: converting ‘false’ to pointer type ‘int*’ [-Werror=conversion-null]
int * foo() {return false;}
^
cc1plus: some warnings being treated as errors
Я получаю те же результаты, если я опускаю #pragma
и вместо этого компилирую с -Werror
. Это также ожидается: согласно документам GCC, предупреждение включено по умолчанию.
К моему удивлению, я могу скомпилировать noerror.cpp
без ошибок. Даже если заголовок <atomic>
подавлял предупреждения и ошибки через #pragma GCC diagnostic ignore
, прагма в моем коде должна снова включить их, но это не так.
Между прочим, clang++
ошибок, как и ожидалось, независимо от того, включен ли заголовок:
error: cannot initialize return object of type 'int *' with an rvalue of type 'bool'
Во-вторых: работа с distcc восстанавливает правильное поведение
У меня несколько рабочих станций. Если я попытаюсь построить локально на любом из них, я столкнусь с описанным выше поведением. Однако, если distcc попытается построить его на любой удаленной машине, ошибка будет выдана корректно. (Именно так я обнаружил эту проблему в первую очередь; наша сборка с высокой вероятностью заставит distcc откатиться к локальной компиляции). На самом деле, даже если у меня есть distcc
SSH к моей собственной машине, правильное поведение (то есть ошибка) восстанавливается:
$ DISTCC_HOSTS='localhost' distcc g++-4.8 -c -std=c++11 noerror.cpp # no error
$ DISTCC_HOSTS='@[my_ip_address]' distcc g++-4.8 -c -std=c++11 noerror.cpp
noerror.cpp: In function ‘int* foo()’:
noerror.cpp:3:21: error: converting ‘false’ to pointer type ‘int*’ [-Werror=conversion-null]
cc1plus: some warnings being treated as errors
Мне непонятно, как distcc
удается восстановить правильное поведение.
Информация о версии: я использую Ubuntu 3.5.0-46-generic
, GCC 4.8.1 и distcc 3.1.
Резюме
Включение <atomic>
, похоже, нарушает диагностику GCC conversion-null
. И каким-то образом использование distcc исправляет это. Я искал, но не смог найти никаких ссылок на подобную ошибку. Является ли эта экспериментальная ошибка известной проблемой или мне следует отправить отчет об ошибке GCC?
[Редактировать: фрагменты кода были взяты с того момента, когда я сделал это предупреждением, а не ошибкой. Вставил исправленную версию]
#pragma GCC diagnostic error
действительно не выглядит хорошей идеей - person user2485710   schedule 21.02.2014<atomic>
отключил эту диагностику внутри с помощью прагм и забыл сбросить ее (например, push, но не pop). Можешь уточнить, почему ты считаешь это плохой идеей? - person Tom   schedule 21.02.2014#pragma
ведет себя непоследовательно. Вы не можете сказать, что это не работает, если такой подход даже не должен работать с самого начала. Просто всегда используйте параметры командной строки, это не то, что вам нужно. - person user2485710   schedule 21.02.2014