gcc -Wall вводит ошибку компилятора

Я пытаюсь использовать компилятор gcc в Keil IDE для микроконтроллера stm32f103. Я компилирую относительно небольшой проект с небольшим количеством кода шаблона и парой чистых виртуальных классов. Никаких причудливых вещей C++11. Все идет нормально.

Когда я компилирую с -w или -pedantic, проект компилируется просто отлично. Но когда я ставлю -Wall, у меня возникает ошибка компиляции в этой части:

template <typename T, typename U>
T & round(T & value, U roundStep)
{   
    UMBA_ASSERT(roundStep > 0);

    UMBA_STATIC_ASSERT( std::numeric_limits<T>::is_integer );
    UMBA_STATIC_ASSERT( std::numeric_limits<U>::is_integer );

    T temp = value / roundStep;
    T remainder = value - temp*roundStep;

    if(remainder < roundStep/2)
    {
        value = temp*roundStep;
    }
    else
    {
        value = (temp+1)*roundStep;
    }

    return value;
}

UMBA_STATIC_ASSERT — это типичное «статическое утверждение C»:

#define UMBA_STATIC_ASSERT_MSG(condition, msg) typedef char umba_static_assertion_##msg[(condition)?1:-1]
#define UMBA_STATIC_ASSERT3(X, L) UMBA_STATIC_ASSERT_MSG(X, at_line_##L)
#define UMBA_STATIC_ASSERT2(X, L) UMBA_STATIC_ASSERT3(X, L)

#define UMBA_STATIC_ASSERT(X) UMBA_STATIC_ASSERT2(X, __LINE__)

Самое смешное, что я даже не могу понять ошибку:

compiling common_functions.cpp...
src/Common_Functions/common_functions.h: In function 'T& common_functions::round(T&, U)':
./src/Global_Macros/global_macros.h(99): warning: typedef 'umba_static_assertion_at_line_131' locally defined but not used [-Wunused-local-typedefs]
 #define UMBA_STATIC_ASSERT_MSG(condition, msg) typedef char umba_static_assertion_##msg[(condition)?1:-1]
./src/Global_Macros/global_macros.h(100): error: note: in expansion of macro 'UMBA_STATIC_ASSERT_MSG'
./src/Global_Macros/global_macros.h(101): error: note: in expansion of macro 'UMBA_STATIC_ASSERT3'
./src/Global_Macros/global_macros.h(104): error: note: in expansion of macro 'UMBA_STATIC_ASSERT2'
src/Common_Functions/common_functions.h(131): error: note: in expansion of macro 'UMBA_STATIC_ASSERT'

Это отличается от ошибки статического утверждения, которая выглядит примерно так: «ошибка: размер массива umba_static_assertion_at_line_21 отрицательный». И, насколько я понимаю, функция round даже нигде в проекте не вызывается.

Вот все опции компилятора на всякий случай; включения в папку Keil помещаются туда автоматически IDE:

-c -mcpu=cortex-m3 -mthumb -gdwarf-2 -MD -Wall -O0 -I./src -I./src/Modules_Config -I./src/CMSIS -I./src/SPL/inc -ffunction-sections -fdata-sections -fno-exceptions -fno-rtti  -mcpu=cortex-m3 -IC:/Keil4.72/ARM/CMSIS/Include -IC:/Keil4.72/ARM/Inc/ST/STM32F10x -DUSE_STDPERIPH_DRIVER -DUSE_FULL_ASSERT -Wa,-alhms="./lst/*.lst" -o *.o

Я не уверен, что с этим делать.


person Amomum    schedule 27.05.2016    source источник
comment
@bolov - в контексте вашего «дубликата» проблема < и > для препроцессора актуальна только тогда, когда также присутствуют запятые, которых здесь нет.   -  person Smeeheey    schedule 27.05.2016
comment
Я попытался поместить выражение внутри UMBA_STATIC_ASSERT в (); это не помогло. И почему он появится только с -Wall?   -  person Amomum    schedule 27.05.2016
comment
Что-то здесь очень не так. В то время как -Wall должно вызывать добавление всех этих строк в ваш вывод, часть error: note: ... должна быть просто note: .... Это примечание, прикрепленное к предупреждению, а не ошибка, поэтому эти примечания не должны вызывать сбой компиляции. Какая это версия GCC? Если вы уменьшите исходный код только до #define MACRO typedef char a[]; / void f() { MACRO }, это также даст ошибку в примечании о расширении макроса?   -  person    schedule 27.05.2016
comment
@hvd arm-none-eabi-gcc.exe (Инструменты GNU для встроенных процессоров ARM) 5.2.1 20151202 (выпуск) [ARM/embedded-5-branch, редакция 231848]. Да, ваш пример тоже выдает ошибку src/main.cpp: In function 'void f()': src/main.cpp(21): warning: typedef 'a' locally defined but not used [-Wunused-local-typedefs] src/main.cpp(26): error: note: in expansion of macro 'MACRO'   -  person Amomum    schedule 27.05.2016
comment
Похоже, у вас также есть -Werror, обрабатывающий предупреждения как ошибки. -w запрещает все предупреждения, поэтому неудивительно, что вы не получаете это предупреждение при его использовании. (В вашей командной строке нет -Wall - вы правильно скопировали?)   -  person molbdnilo    schedule 27.05.2016
comment
@molbdnilo Я скопировал командную строку, которая не выдает ошибки; изменение -pedantic с -Wall производит его. Там нет -Werror, я почти уверен. Есть и другие предупреждения, и они не выдают ошибки. Я, наверное, изменю пост, чтобы не было путаницы.   -  person Amomum    schedule 27.05.2016
comment
@hvd Я только что попробовал последнюю доступную сборку для win32 (5.3.1 20160307 (выпуск) [ARM/embedded-5-branch, редакция 234589]); ошибка все еще там.   -  person Amomum    schedule 27.05.2016
comment
@Amomum Сбойная командная строка гораздо более актуальна для сбоя, чем безуспешная. (Скопируйте и вставьте и будьте уверены, не описывайте, не предполагайте и не будьте почти уверены.)   -  person molbdnilo    schedule 27.05.2016
comment
@molbdnilo Я понимаю твою точку зрения; Я обновил свой пост.   -  person Amomum    schedule 27.05.2016
comment
Но помимо всего этого: -Wall включает -Wunused-local-typedefs и, как говорится в сообщении, макрос вводит неиспользуемый локальный typedef, так что...   -  person molbdnilo    schedule 27.05.2016
comment
Вы пытались вызвать компилятор из командной строки и посмотреть, происходит ли это? У меня были ошибки IDE, из-за которых предупреждения GCC ошибочно принимались за ошибки.   -  person feersum    schedule 27.05.2016
comment
Попытка с компилятором из GCC ARM Embedded в Launchpad, который сообщает о себе как о gcc версии 5.3. 1 20160307 (выпуск) [ARM/embedded-5-branch, редакция 234589] (Инструменты GNU для встроенных процессоров ARM), как вы сказали, и точная командная строка из вашего вопроса, и мой двухстрочный исходный файл из комментариев здесь, это не компилируется, поскольку "./lst/*.lst" -o *.o недействителен, что может вводить в заблуждение при выводе IDE. При изменении этого, чтобы указать имена файлов, компиляция завершается успешно.   -  person    schedule 27.05.2016
comment
Компиляция @hvd из командной строки действительно выдает предупреждение, но не ошибку. Мне кажется, что Fersum прав: вывод IDE неправильно анализирует вывод компилятора.   -  person Amomum    schedule 27.05.2016
comment
@feersum, кажется, ты прав. Не могли бы вы сделать свой комментарий и ответить, чтобы я мог принять его?   -  person Amomum    schedule 27.05.2016


Ответы (2)


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

person feersum    schedule 27.05.2016

Причина ошибки довольно проста:

./src/Global_Macros/global_macros.h(99): предупреждение: typedef 'umba_static_assertion_at_line_131' определен локально, но не используется [-Wunused-local-typedefs]

Ваш классический макрос статического утверждения в стиле C работает, создавая typedef, который будет плохо определен, если утверждение завершится ошибкой, или просто не будет использоваться, если утверждение пройдет успешно. Однако -Wall включает -Wunused-local-typedefs, который генерирует предупреждение, если вы создаете typedef, но не используете его. Я подозреваю, что вы также включили опцию обработки предупреждений как ошибок.

person Stephen C. Steel    schedule 27.05.2016
comment
Вы частично правы. Причина, по-видимому, в том, что многострочное предупреждающее сообщение неправильно анализируется моей IDE. Компиляция из командной строки с той же опцией компилятора дает тот же тест, только error: note — это просто note:. Невозможно рассматривать предупреждения как ошибки, поскольку другие предупреждения не приводят к ошибкам. - person Amomum; 28.05.2016