Я поддерживаю программу с открытым исходным кодом, и один из моих пользователей сообщил, что она не будет компилироваться под clang
, который я никогда не использовал раньше. Одна из ошибок, которые я получаю, * Предупреждение: квалификатор для типа функции ‘junky_t’ (он же void (const int) &, const int &) ‘) имеет неопределенное поведение. *. Я создал небольшую программу, которая демонстрирует проблему:
typedef void junky_t(const int &foo,const int &bar);
class demo {
public:;
const junky_t *junk;
};
И вот что происходит, когда я пытаюсь скомпилировать:
$clang -DHAVE_CONFIG_H -g -g -O3 -Wall -MD -Wpointer-arith -Wshadow -Wwrite-strings -Wcast-align -Wredundant-decls -Wdisabled-optimization -Wfloat-equal -Wmultichar -Wmissing-noreturn -Woverloaded-virtual -Wsign-promo -funit-at-a-time -Weffc++ -D_FORTIFY_SOURCE=2 -MT demo.o -MD -MP -c -o demo.o demo.cpp
demo.cpp:5:5: warning: qualifier on function type 'junky_t' (aka 'void (const int &, const int &)') has unspecified behavior
const junky_t *junk;
^~~~~~~~~~~~~
1 warning generated.
То есть класс demo
имеет указатель на функцию с сигнатурой, которая принимает несколько константных ссылок. const
в классе demo
должен предотвратить junk
от того, чтобы быть измененным. Однако, по-видимому, это неоднозначно, потому что сама функция может рассматриваться const
, что это не так. У меня нет проблем с компиляцией gcc
или же llvm
но это не скомпилируется с clang
на Mac. Что я должен делать?
Это не неуточненное поведение. Предупреждение о лязге неверно. Ваш код легален с ++. Стандарт (C ++ 11) гласит, что cv-квалификаторы поверх типа функции игнорируются.
Следовательно, нет смысла помещать константный квалификатор поверх функционального типа. Если вы хотите, чтобы ваш указатель был постоянным, напишите
junky_t * const junk;
в противном случае просто напишите
junky_t * junk;
Других решений пока нет …