2014-11-06 3 views
5

В моем внедренного проекта, используя IAR EWARM Dev инструменты (v7.10.3), я следующий кусок кода:Почему компилятор IAR застревает?

/* 1 */ uint32_t packet_sync = 0; 
/* 2 */ uint32_t synced  = 0; 
/* 3 */ uint32_t gpio  = 0; 

/* 4 */ while (1) { 
/* 5 */  if ((packet_sync != 0) && ((packet_sync = gpio) == 0)) { 
/* 6 */  if (synced < 2) { 
/* 7 */   synced++; 
/* 8 */  } 
/* 9 */  } 
/* 10 */ }; 

С какой-то причине, когда я компиляции кода, компилятор застревает в в середине компиляции. Я попытался поиграть с различными конструкциями, и, похоже, любые незначительные изменения, которые я делаю, устраняет проблему (но может также сделать код неправильным). Например, добавление NOP в # 6а, а код делает компиляции успешно:

/* 6 */  if (synced < 2) { 
/* 6a */   __NOP(); 
/* 7 */   synced++; 
/* 8 */  } 

Другие примеры успешных изменений удаления строки # 7 или изменение линии № 5, как:

/* 5 */  if ((packet_sync != 0) && ((gpio) == 0)) { 

и еще несколько вариантов.

Я не вижу нарушения правила C в проблемном коде, и он просто компилируется в Visual Studio 2013. Я что-то пропустил? Почему этот код не компилируется?

* Примечание: представленный код является выпиской из фактического кода и является логически бессмысленным.


Update: код компилируется с "High"/"Сбалансированный" уровень оптимизации. При более низких уровнях оптимизации компиляция заканчивается просто отлично.

Он также застревает при использовании «Высокого» уровня, но удаляет параметры оптимизации в поле «Включенные преобразования:». Также застрял для опций «Скорость» и «Размер».

+0

Какие параметры компилятора вы используете, и результаты изменяются, если, например, вы включаете/выключаете оптимизацию или используете компиляцию C++, а не C ?. Поскольку вы не знаете, в чем проблема, как вы можете быть уверены, что представление «абстрактного» является достаточной информацией для воспроизведения проблемы? Код, конечно же, не «SSCCE», как вы утверждаете! – Clifford

+0

В первом фрагменте 'gpio' является инвариантом цикла. Если он может быть изменен в другом контексте, он должен быть объявлен 'volatile'. Другие переменные также могут быть объявлены 'volatile' в зависимости от использования в другом месте кода. – Clifford

+0

@Clifford - я не требовал SSCCE. Один «C» для компиляции был удален, так как этот код необходимо обернуть соответствующей функцией. 'gpio' действительно инвариантен (в коде извлечения). Код был представлен как определено в проекте. Никакие переменные нестабильны. Вы правы в том, что я не упоминал, что код * размер * оптимизирован. К сожалению, трудно удалить оптимизацию без какой-либо масштабной доработки проекта. – ysap

ответ

2

Если компилятор буквально «застревает», т. Е. Замерзает, поэтому вам нужно убить процесс, тогда это, конечно, ошибка компилятора.

Выяснение причин, почему кусок кода (= компилятор) мы не видели перерывов для конкретного ввода очень сложно.

Если, с другой стороны, вы имеете в виду, что компилятор останавливается, потому что он сообщает об ошибке в вашем коде, тогда, конечно, было бы полезно знать это и то, что он говорит.

+0

Процесс застревает, и я должен нажать кнопку «Остановить сборку», чтобы остановить его. Отчет об ошибках не указан. – ysap

+1

Конечно, это очень сложно ... иначе я бы не поставил вопрос здесь ;-) – ysap

+0

@ysap Я был слегка ироничным. Я бы сказал, что то, что вы просите, в принципе невозможно определить дистанционно. Есть ли коммерческая поддержка для компилятора? – unwind

2

Я подозреваю, что это ошибка компилятора. Рассмотрите возможность подачи ошибки с поставщиком компилятора и убедитесь, что вы подключили неисправный исходный код, чтобы они могли воспроизвести ошибку компилятора. Вам не повезло. Попытайтесь обойти эту ошибку сейчас.

+0

Спасибо. Вы в основном правы, но, пожалуйста, посмотрите мой комментарий на @unwind. – ysap

+1

Создайте MCVE, показывающий ошибку, чтобы получить хорошую поддержку от поставщика, они не смогут ее исправить или потратить на нее, если они не смогут воспроизвести –

2

Оптимизация - самая сложная часть любого компилятора и, следовательно, наиболее вероятное место для компилятора - особенно для компилятора «узкого рынка» с небольшой командой разработчиков и меньшего числа, если пользователи используют компилятор настольных систем.

Применение оптимизации имеет два последствия, о которых вам следует относиться с осторожностью; Сам компилятор может быть ошибкой (как представляется, в этом случае), и любая область «неопределенного поведения» в вашем собственном коде может изменить поведение при оптимизации. Если вам нужно использовать оптимизацию, вам нужно быть готовым к проверке широко - сгенерированный код не обязательно эквивалентен сборке отладки/разработки.

В этом случае вы должны обязательно сообщить об этом поставщику, в идеале, с действительно составленным примером и конфигурацией проекта.Чтобы решить вашу непосредственную проблему, разумное использование ключевого слова volatile может решить проблему - оптимизатор будет работать, чтобы устранить переменные, которые, как представляется, не имеют никакого эффекта, - если вы можете избежать того, что оптимизатор использует тот же путь, вы можете избежать ошибки. Если вы не используете volatile правильно, your code may well exhibit bugs в любом случае при оптимизации. В вашем примере некоторые переменные, безусловно, должны быть объявлены нестабильными, но поскольку этот пример не является «реальным», а «иллюстративным», это невозможно сообщить.

Другая возможность в качестве обходного пути - выборочно отключать оптимизацию для этого раздела кода или исходного файла. Вам действительно нужна оптимизация, чтобы ваш код работал вообще? Если нет, я бы посоветовал избежать этого в любом случае - не используя оптимизацию, избегает изменений в поведении между отладочным и выпущенным кодом и упрощает отладку в первом случае. Я бы посоветовал использовать оптимизацию в качестве решения проблемы с размером кода или проблемами, связанными с производительностью, когда и если они возникают, а не как само собой разумеющееся.

+0

Спасибо. Это все правда и известные факты. В фактическом коде 'gpio' объявляется соответствующим образом. Более того, я позже заменил его на «0», и проблема не устранена, поэтому волатильность выражения не является ее источником. Как я заметил в вопросе, легко обойти это, просто добавив инструкцию 'NOP' внутри' if'. Точки, касающиеся оптимизации, действительны, но в этом случае код уже переполняет память ЦП, будучи критическим путем, поэтому уменьшение размера является обязательным, а также увеличение скорости. Во всяком случае, отчет об ошибке был отправлен вчера. – ysap

+0

@ysap: В этом случае я думаю, что нам нужно отказаться от этого - мы обсуждаем фрагмент кода, который не является репрезентативным и вряд ли позволит кому-то другому с тем же инструментом воспроизвести проблему. Кроме того, кажется, что речь идет о инструменте или о программировании как таковом. Это, вероятно, не должно было мигрировать здесь. – Clifford