Ожидаемая ошибка выражения - PullRequest
1 голос
/ 10 ноября 2011

У меня следующий код C ++ и запускается ПК-код на код.

Вопрос 1:

#if !WIN32
#define ULONG_MAX 0xffffffff
#endif

Выше кода выдает ошибку lint следующим образом

Ошибка 26: ожидалось выражение, найдено 'WIN32'
Ошибка 30: ожидается целочисленная константа

Как исправить вышеуказанную ошибку?

Вопрос 2:

const char CompanyName[] = "mycompany"; 

Ошибка: примечание 960: нарушает требуемое правило 8.5 MISRA, в заголовочных файлах нет определений объектов / функций

Как исправить вышеуказанную ошибку?

Вопрос 3:

unsigned long m_ClientThreadId; 
m_ClientThreadId        = 0;

Примечание 960: Нарушение MISRA Обязательное правило 10.1, Неявное преобразование подписи

Как исправить вышеуказанную ошибку?

Ответы [ 6 ]

4 голосов
/ 10 ноября 2011

Первый:

Вам нужно сделать это вместо:

#ifndef WIN32
#define ULONG_MAX 0xffffffff
#endif

Второе:

Вы не можете определить это в заголовочном файле, иначе один и тот же символ появится в нескольких единицах компиляции.

Что вам нужно сделать вместо этого, это просто объявить в шапке:

extern const char CompanyName[];

А затем определите его один раз в одном из модулей:

const char CompanyName[] = "mycompany"; 

Третье:

unsigned long m_ClientThreadId; 
m_ClientThreadId        = 0;

Это необычно, но кажется, что 0 - это константа со знаком. И присвоение этому unsigned long имеет неявное приведение типа. Большинство компиляторов на самом деле не предупреждают об этом.

2 голосов
/ 10 ноября 2011

Несколько моментов требуют уточнения. Например, строка:

#if !WIN32

на самом деле хорошо определено стандартом и может быть разумно использовано если ваши вызовы компилятора всегда содержат /DWIN32=1 или -DWIN32=0. В этом отношении стандарт говорит, что символы, которые не определены, заменяется на 0 при расширении макроса, поэтому проблем не возникает с линией , если в некоторых других соглашениях не указано, что символ будет определяться только на машинах Windows, но значение, которое оно определено для не указано; в этом случае вам нужно что-то вроде:

#ifndef WIN32

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

С другой стороны, следует избегать строки, которая следует сразу за так как он определяет символ (ULONG_MAX), который определен в C и Стандарты С ++. Последовательность из трех строк здесь должна быть заменена на:

#include <limits.h>

Что касается второго вопроса, я не уверен, что ошибка не неправильное толкование правила MISRA. В C ++ const подразумевает внутренний связь по умолчанию: определение символа в заголовке вызовет несколько экземпляров переменной (с другим адресом в каждая единица перевода), но не вызовет проблем с несколькими определения. И альтернативы также имеют свои недостатки. мой предпочтение здесь будет состоять в том, чтобы заменить определение переменной макрос:

#define CompanyName "mycompany"

но у макросов есть свои проблемы. Объявление символа extern, и затем определение его в одном (и только одном) исходном файле является другим альтернатива, но это включает в себя два утверждения, в двух разных файлах, где (в зависимости от роли, которую играет переменная), можно предпочтительнее. (Судя по названию, я не думаю, что два заявления было бы проблемой, но есть и другие случаи, когда предпочтительнее оставьте текст видимым в заголовке.) Оставьте его, как вы написали также является жизнеспособной альтернативой, если ваша компания не имеет строгих правил против этого.

Что касается последней точки, выражение 0 имеет тип int, который подписано Можно четко указать тип 0UL, но, честно говоря, этот не должно быть необходимо: 0 равно 0, независимо от типа, и в то время как могут быть случаи, когда вы хотите форсировать тип, чтобы арифметика происходит определенным образом, это не один из них. Что касается ошибка / предупреждение, я подозреваю, что это также неверное толкование правила MISRA; неявные преобразования, которые изменяют подпись, могут быть проблематично, но не тогда, когда то, что превращается, очень мало неотрицательное постоянное целое число. Так что пишите 0UL если вам нужно придерживаться к правилам компании, но понимаете, что это точка глупости: случай в основном здравого правила, применяемого в случаи, когда это не актуально.

1 голос
/ 10 ноября 2011

Для первого вопроса, я думаю, вы должны использовать

#ifndef WIN32

вместо

#if !WIN32

, поскольку макрос WIN32 не всегда существует, и вам нужно проверять его существование, а не его "ложность".

0 голосов
/ 10 ноября 2011

Ни одна из этих зарегистрированных ошибок не является ошибками C ++;это проблемы стиля.

Первый:

#if !WIN32
#define ULONG_MAX 0xffffffff
#endif

Это законно.В директиве #if любой токен, который не определен, заменяется на 0.Но, вероятно, лучше написать #ifndef WIN32, как уже предлагали другие.

Но на самом деле все это, вероятно, плохая идея.ULONG_MAX - это макрос, определенный в стандартном заголовке C <limits.h> и стандартном заголовке C ++ <climits>.Замените вышеупомянутые 3 строки на:

#include <climits>

Секунда:

const char CompanyName[] = "mycompany";

Правовая, но плохая идея.Если заголовочный файл #include d из разных единиц перевода, у вас будет несколько определений CompanyName.(Я не совсем уверен, что правила C ++ говорят об этом.) См. Ответ Mysticial.

Третий:

unsigned long m_ClientThreadId; 
m_ClientThreadId        = 0;

Здесь PC-lint слишком перегруженразборчивы.Да, неявное преобразование 0 (типа int) в unsigned long действительно меняет подпись, но в этом случае это не вызывает никаких возможных проблем.Но вы можете избежать предупреждения, используя литерал типа unsigned long:

unsigned long m_ClientThreadId; 
m_ClientThreadId        = 0UL;
0 голосов
/ 10 ноября 2011

Там также #if !defined(WIN32), но #ifndef WIN32 легче понять.

0 голосов
/ 10 ноября 2011

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

...