Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > GCC варнинги компиляции


Автор: shara 6.6.2013, 15:27
Приветствую

собсно вопрос, 
есть ли в GCC способ "програмно" отключить некоторые из варнингов компиляции?

по принципу как в M$VC

Код

#pragma warning( disable : <номер предупреждения> )


собсно варниг на который ругаицца 
Код

warning: the address of ‘some_variable_name’ will never be NULL [-Waddress]


В данном конкретном случае варнинг не имеет смысла. Но хочется оставить такую проверку для остальных частей проекта..

Автор: borisbn 6.6.2013, 17:04
Лови - http://forum.vingrad.ru/forum/topic-350156/anchor-entry2500255/0.html - я уже спрашивал именно это. Мне помогли

Автор: shara 10.6.2013, 11:54
Спасибо помогло  smile 
Код

#pragma GCC diagnostic ignored "-Waddress"
//some warning code here
#pragma GCC diagnostic warning "-Waddress"

Автор: borisbn 10.6.2013, 11:58
а ещё лучше будет збавиться от этого
Цитата(shara @  10.6.2013,  11:54 Найти цитируемый пост)
//some warning code here

 smile 

Автор: shara 10.6.2013, 12:17
иногда просто нет возможности избавиться от этого.

Пример из реального проекта:
Код

    /**
     *  General purpose buffer structure
     */
    typedef struct _sdrm_buff{
        Byte* data;  /**< Pointer to the buffer data */
        Uint32 sz;    /**< Data size */
    }Buffer;

#define INIT_BUFFER_FROM_RAW(b, pr, rs) do{\
    (b).data = NULL; \
    (b).sz = 0; \
    if (NULL != (pr)) {\
        MALLOC_BUFFER(b, (rs)); \
        if((b).data != NULL) \ // вот тут ругаицца
        { \
            memcpy((b).data,(pr),(rs));\
        } \
    }\
}while(0)

.....

  Buffer devSecLevel = {0};
  int      devSecLevelGetFromUser = getSomeInt()'

#pragma GCC diagnostic ignored "-Waddress"
   INIT_BUFFER_FROM_RAW(devSecLevel, &jdevSecLevel /* а вот тут обычно указатель */,   1 /* !!! */ );
#pragma GCC diagnostic warning "-Waddress"

Автор: volatile 10.6.2013, 23:34
Цитата(shara @  10.6.2013,  12:17 Найти цитируемый пост)
if((b).data != NULL) \ // вот тут ругаицца


Автор: shara 11.6.2013, 10:20
Цитата(volatile @  10.6.2013,  22:34 Найти цитируемый пост)
if((b).data != NULL) \ // вот тут ругаицца

 smile  

ИМХО вопрос вкуса. Видать автору так было наглядней\привычней
(и кстати компиллер все равно ругается)

Автор: borisbn 11.6.2013, 10:40
Уже с час сижу и не могу понять, почему компилятор ругается на проверку того, что некий указатель не равен NULL  smile 
Просветите, плиз.

Добавлено через 2 минуты и 11 секунд
Я бы ещё понял, если бы тут
Цитата(shara @  10.6.2013,  12:17 Найти цитируемый пост)
if (NULL != (pr)) {\

где pr это & jdevSecLevel, который, действительно, не м.б. NULL

Добавлено через 8 минут и 1 секунду
И ещё. ИМХО лучше избавиться не отключением warning'а (при чём компиляторозависимым), а так
Код

Buffer devSecLevel = {0};
...
// Седующая строчка ОБЯЗАТЕЛЬНА, чтобы тот, кто в будущем будет читать не ломал бы голову, зачем так сделано
// Создаём указатель, для того, чтобы избавиться от warning'а в макросе INIT_BUFFER_FROM_RAW
const Buffer * tempDevSecLevelPtr = & devSecLevel;
INIT_BUFFER_FROM_RAW( devSecLevel,  tempDevSecLevelPtr ... 

Автор: volatile 11.6.2013, 13:48
Цитата(shara @  11.6.2013,  10:20 Найти цитируемый пост)
и кстати компиллер все равно ругается) 

Приведите минимальный вариант кода, который можно скомпилить и где он ругаецца. 

Цитата(shara @  11.6.2013,  10:20 Найти цитируемый пост)
if(b.data != NULL) \ // вот тут ругаицца

Если вы еще не забыли коммент убрать, то вообще замечательно.

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

Автор: shara 11.6.2013, 19:31
Цитата(volatile @  11.6.2013,  12:48 Найти цитируемый пост)
Если вы еще не забыли коммент убрать, то вообще замечательно.

комент писан руками специально чтобы указать "проблемное" место. Не придирайтесь пожалуйста  

Цитата(volatile @  11.6.2013,  12:48 Найти цитируемый пост)
Приведите минимальный вариант кода, который можно скомпилить и где он ругаецца. 


Код

#include <stdio.h>
void main ()
{
  int a = 42;

  if (&a != NULL) {
    printf("&a will never be NULL");
  }
  else {
    printf("oh shit!");
  }
}

 простите, забыл сказать проект компилится с флагом -Wall (aka, хАчу все варнинги smile )
Код

user@ubuntu64:~/workspace/test$ gcc -Wall test.c -o test 
test.c:2:6: warning: return type of ‘main’ is not ‘int’ [-Wmain]
test.c: In function ‘main’:
test.c:6:9: warning: the comparison will always evaluate as ‘true’ for the address of ‘a’ will never be NULL [-Waddress]
user@ubuntu64:~/workspace/test$ ./test 
&a will never be NULL




Макрос   INIT_BUFFER_FROM_RAW, как несложно догадаться из названия, писан для того чтобы инитить Buffer общего типа некими данными, на которые указывать указатель  smile  (есесно мы должны знать размер этих данных)
Код  зашибисть работает. "проблемы" начались когда в этот самый буфер захотелось втолкать число, хранится в обыкновенном инте. Известно что инт обыкновенный создается на стеке, в следсвии чего его адрес никогда не будет нуль, о чем компилятор собсно и ругается. 

В общем,  вместо тысячи слов:
Код

#include <string.h>
#include <stdlib.h>

   //to make this staf compil
   typedef unsigned char Byte;
   typedef unsigned int  Uint32;

   /**
     *  General purpose buffer structure
     */
    typedef struct _buff{
        Byte* data;  /**< Pointer to the buffer data */
        Uint32 sz;   /**< Data size */
    }Buffer;

#define INIT_BUFFER_FROM_RAW(b, pr, rs) do{\
    (b).data = NULL; \
    (b).sz = 0; \
    if (NULL != (pr)) {\
        (b).sz = rs; \
        (b).data = malloc(rs); \
        if((b).data != NULL) \
        { \
            memcpy((b).data,(pr),(rs));\
        } \
    }\
}while(0)

int main (void)
{
/* p0 */
  Buffer devSecLevel0 = {0};
  char someData[] = "some random data, just lazy to write more code" ;

  INIT_BUFFER_FROM_RAW(devSecLevel0, someData,   sizeof(someData) ); // almost normal workflow


/* p1 */
  Buffer devSecLevel1 = {0};
  int    devSecLevelGotFromUser1 = 42;

  INIT_BUFFER_FROM_RAW(devSecLevel1, &devSecLevelGotFromUser1,   1 /* one byte */ ); // warning!!!

/* p2 */
  Buffer devSecLevel2 = {0};
  int    devSecLevelGotFromUser2 = 42;
  int  *pdevSecLevelGotFromUser2 = &devSecLevelGotFromUser2;

  INIT_BUFFER_FROM_RAW(devSecLevel2, pdevSecLevelGotFromUser2,   1 /* one byte */ ); // NO warning!
// IMHO it is better to make compiller shut up at this moment either than writing this sado-mazo code
  return 0;
}




Спасибо за внимание и время уделенное моей скромной персоне.

Автор: shara 11.6.2013, 19:59
Цитата(borisbn @  11.6.2013,  09:40 Найти цитируемый пост)
И ещё. ИМХО лучше избавиться не отключением warning'а 

Чем лучше?
На вкус и цвет ИМХИ разные.
Вводить лишнюю переменную как-то лениво (и расточительно). Конечно умный кмопиллер это скорей всего с оптимизирует. Но быть может пускай он просто молча скомпилит код. Тем паче отключающая варнинг директива четко указывать на то что девелопер: 
первое как минимум смотрит варнинги
второе, подумал и решил отключить сей конкретный варнинг.

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

Цитата(borisbn @  11.6.2013,  09:40 Найти цитируемый пост)
(при чём компиляторозависимым), а так

GCC наше все

Автор: borisbn 11.6.2013, 22:59
Цитата(shara @  11.6.2013,  19:59 Найти цитируемый пост)
Вот представьте, вы читаете чужой код - а там не пойми зачем камасутру делают.. и у вас начинает вещество работать, думать, а зачем, а что,  а как? 

Цитата(borisbn @  11.6.2013,  10:40 Найти цитируемый пост)
// Седующая строчка ОБЯЗАТЕЛЬНА, чтобы тот, кто в будущем будет читать не ломал бы голову, зачем так сделано
// Создаём указатель, для того, чтобы избавиться от warning'а в макросе INIT_BUFFER_FROM_RAW

Кста, я не случайно выделил слово ОБЯЗАТЕЛЬНО

Автор: volatile 11.6.2013, 23:41
shara, вы это писали
Цитата(shara @  10.6.2013,  12:17 Найти цитируемый пост)
      if((b).data != NULL) \ // вот тут ругаицца
        

В этом месте он ругацца никак не может. Так что вы ввели в заблуждение и нас и себя.

Цитата(shara @  11.6.2013,  19:31 Найти цитируемый пост)
забыл сказать проект компилится с флагом -Wall 

Каждый сам выбирает себе крест, в меру своей параноидальности.
Вы его выбрали, ну так и несите с высоко поднятой головой.
borisbn, предложил вам использовать лишний указатель, имхо вполне нормальный выход, в вашем случае  smile 
Цитата(shara @  11.6.2013,  19:59 Найти цитируемый пост)
Вводить лишнюю переменную как-то лениво. 

Или вы хотите и рыбку съесть и палец о палец даже не ударить. smile 

И последнее, если вы все-же желаете вводить прагмы, то вы так и не привели пример того, где она не срабатывает.
Цитата(shara @  10.6.2013,  12:17 Найти цитируемый пост)
иногда просто нет возможности избавиться от этого.

где нет возможности то? Если в ваш код вставить
#pragma GCC diagnostic ignored "-Waddress",
варнингов не будет. Зачем вы тему второй раз подняли?

Автор: shara 12.6.2013, 11:57
Цитата(volatile @  11.6.2013,  22:41 Найти цитируемый пост)
В этом месте он ругацца никак не может. Так что вы ввели в заблуждение и нас и себя.

Да, не там коммент написал  smile 

Тему второй раз поднимать не хотел. Вы спрашивали я отвечал.. 

Свой ответ я получил во втором сообщении.
Все что ниже  - дискуссия о вкусах (с примесью моих опечаток) 

Всем спасибо  smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)