URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID3
Нить номер: 73416
[ Назад ]

Исходное сообщение
"Корректирующий релиз набора компиляторов GCC 4.5.2"

Отправлено opennews , 17-Дек-10 16:12 
Вышел корректирующий релиз набора компиляторов GCC 4.5.2 (http://gcc.gnu.org/), в котором проведена работа по исправлению ошибок, регрессивных изменений и проблем с совместимостью. С момента выхода прошлой версии отмечено (http://gcc.gnu.org/bugzilla/buglist.cgi?bug_status=RESOLVED&...) 75 исправлений, большинство из которых связанно с устранением внесенных ранее регрессивных изменений. Исходные тексты компилятора можно загрузить с сайта проекта (ftp://gcc.gnu.org/pub/gcc/releases/gcc-4.5.2/) или с его зеркал (http://gcc.gnu.org/mirrors.html).

URL: http://gcc.gnu.org/
Новость: http://www.opennet.me/opennews/art.shtml?num=29031


Содержание

Сообщения в этом обсуждении
"Корректирующий релиз набора компиляторов GCC 4.5.2"
Отправлено k0l0b0k , 17-Дек-10 16:12 
во. интересно, avr-g++ пофиксили?

"Корректирующий релиз набора компиляторов GCC 4.5.2"
Отправлено Аноним , 17-Дек-10 17:47 
Он никогда и не ломался.

"Корректирующий релиз набора компиляторов GCC 4.5.2"
Отправлено k0l0b0k , 17-Дек-10 18:48 
4.5.1 сегфолтится на моем "изобретении". багрепорт решил не писать до обновления. Вот до арча 4.5.2 доползет - попробую...

"Корректирующий релиз набора компиляторов GCC 4.5.2"
Отправлено Аноним , 18-Дек-10 00:45 
> 4.5.1 сегфолтится на моем "изобретении". багрепорт решил не писать до обновления. Вот до арча 4.5.2 доползет - попробую...

Ага, жди у моря погоды.


"Корректирующий релиз набора компиляторов GCC 4.5.2"
Отправлено anon2 , 17-Дек-10 21:12 
gcc уже научился компилить _работающий_ код следующего примера,
ну или не компилить, хотя бы с warning'ом, хотя бы при -pedantic -Wall

$cat x.c

struct A
{
    int k;
};

int foo(struct A *a)
{
    {
        struct A *a = a;
        return a->k;
    }
}

int main(int argc, char *argv[])
{
    struct A s = {111};
    return foo(&s);
}

$gcc -Wall -pedantic x.c; ./a.out; echo $?
72

$gcc -Wall -pedantic -O2 x.c; ./a.out; echo $?
SIGSEGV


А то страшно писать код с макросами вида

#define DUMP(x) \
  do { \
    struct A *a = x; \
    printf("%d,%d\n", a->k1, a->k2); \
  } while (0)


потому что при вызове

DUMP(a);

программа падает по SIGSEGV.


"Корректирующий релиз набора компиляторов GCC 4.5.2"
Отправлено Аноним , 17-Дек-10 22:16 
> struct A *a = a;

Поздравляю, вы выиграли медаль «Гений программирования».


"Корректирующий релиз набора компиляторов GCC 4.5.2"
Отправлено anon2 , 17-Дек-10 23:36 
>> struct A *a = a;
> Поздравляю, вы выиграли медаль «Гений программирования».

Чуть-чуть сильнее напрягите извилины.
Это сейчас очевидно где ошибка.
Вывод в том, что при написании макроса с объявлением локальной переменной во вложенном блоке, например в do {} while (0), нужно следить, чтобы имя переменной было уникально и макрос не раскрылся в
struct A *a = a;


"Корректирующий релиз набора компиляторов GCC 4.5.2"
Отправлено BSA , 17-Дек-10 23:50 
именно поэтому:
1. макросы зло
2. имена переменных в них нужно выбирать такими, чтобы вероятность получить подобную ошибку была практически нулевой. Например, используя 2 подчеркивания в середине имени переменной.

"Корректирующий релиз набора компиляторов GCC 4.5.2"
Отправлено Аноним , 18-Дек-10 02:05 
> нужно следить, чтобы имя переменной было уникально

Ну так и поручите это компилятору. Хорошо, я Вам покажу как это сделать:

#define DUMP(x) \
  do { \
    struct A *tmp_##x = x; \
    printf("%d,%d\n", tmp_##x->k1, tmp_##x->k2); \
  } while (0)

Теперь у Вас имя временной переменной никогда не совпадёт с аргументом макроса, потому что имя временной переменной строится из имени аргумента макроса с добавлением префикса tmp_

Но у Вас проблема не только в этом, сам макрос выглядит глупо. Во-первых, зачем вообще временная переменная? Во-вторых, какой смысл такого макроса, Вы же не будете для каждого типа структур писать свой DUMP()?


"Корректирующий релиз набора компиляторов GCC 4.5.2"
Отправлено ram_scan , 18-Дек-10 17:13 
Независимо от степени одаренности программиста компилятор за такие фокусы должен больно бить по рукам, голове и жопе, а не сегфолтиться.

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


"Корректирующий релиз набора компиляторов GCC 4.5.2"
Отправлено anon2 , 18-Дек-10 18:51 
>     struct A *tmp_##x = x; \

оператора ## нет в стандарте с89

> зачем вообще временная переменная?

чтобы поведение кода не изменилось после замены макроса на функцию.
Например DUMP(k++) увеличил k только один раз.

> Вы же не будете для каждого типа структур писать свой DUMP()?

Конечно буду. Поскольку у разных структур свой набор полей.


"Корректирующий релиз набора компиляторов GCC 4.5.2"
Отправлено anon2 , 18-Дек-10 19:05 
> оператора ## нет в стандарте с89

хотя нет, есть.
Но помню с ним были какие-то проблемы, в частности компилятор от MS с ним работает немного по-другому нежели gcc.


"Корректирующий релиз набора компиляторов GCC 4.5.2"
Отправлено Анонимбус , 18-Дек-10 23:30 
>> оператора ## нет в стандарте с89
>хотя нет, есть.

А даже если и так. Ещё лет 10 под C89 писать будете? Имея ввиду экзотические возможные условия героического псевдопортирования? А ведь на дворе 2011-ый год уже...


"Корректирующий релиз набора компиляторов GCC 4.5.2"
Отправлено Аноним , 19-Дек-10 17:37 
Имхо, вы занимаетесь ерундой. Почему макрос, а не функция? Хотите сэкономить полтора машинных такта в 2010 году? Пишите отладочную функцию, во время отладки замедление нестрашно (если оно вообще будет заметно), а после удалите определение функции и сделайте пустой макрос. #ifdef в помощь

"Корректирующий релиз набора компиляторов GCC 4.5.2"
Отправлено anon2 , 20-Дек-10 17:03 
> Почему макрос, а не функция?

Макрос имеет преимущества: __LINE__ и __FILE__.
Для отладки бывает полезно знать, по каким веткам работает код, особенно если это state-машина, да еще на кернеле.
Писать вызов функции
DUMP(k, __LINE__, __FILE__)
длиннее чем вызов макроса
DUMP(k)

> замедление нестрашно

никакого замедления: static inline функция практически эквивалентна макросу.
Можно еще добавить __attribute__((always_inline)) для полной уверенности :)


"Корректирующий релиз набора компиляторов GCC 4.5.2"
Отправлено Прохожий старый анонимус , 21-Дек-10 11:04 
А почему не функция с переменным числом параметров ? Ну как-то так

void mylog(const char *f, ...) {
  static struct tm *curr;
  static time_t curr_t;
  static char w[100];
  va_list args;

  curr_t = time(NULL);
  curr = localtime(&curr_t);
  strftime(w, 100, "%d-%m-%y %T", curr);
  fprintf(stdout, "%s ", w);

  va_start (args, f);

  vfprintf (stdout, f, args);
  va_end (args);
  fprintf(stdout, "\n");
  fflush(stdout);

}

Потом сам вызов можно делать из макроса с автоматической подстановкой номера строки и имени файл. Для подключения функции нужен соответствующий хидер,а в нем разбор значения какой-нибудь DEBUG. В общем тут уже писали - на дворе 21 век и надо все-таки как-то соответствовать.


"Корректирующий релиз набора компиляторов GCC 4.5.2"
Отправлено Sylvia , 17-Дек-10 21:23 
GCC 3.4.6, 4.1.2, 4.2.4 этот код с -Wall -pedantic -O2 собирают и он выполняется без сегфолта, проблема началась с серии 4.3 и присутствует в 4.4 4.5 и 4.6

clang 2.8 собирает без предупреждений но выдает Illegal instruction

icc10 - 12:


icc12: command line remark #10148: option '-pedantic' not supported
x.c(9): warning #592: variable "a" is used before its value is set
          struct A *a = a;
                        ^

icc: command line remark #10148: option '-pedantic' not supported
x.c(6): remark #1418: external function definition with no prior declaration
  int foo(struct A *a)
      ^

x.c(9): remark #1599: declaration hides parameter "a" (declared at line 6)
          struct A *a = a;
                    ^

x.c(9): warning #592: variable "a" is used before its value is set
          struct A *a = a;
                        ^

x.c(6): remark #869: parameter "a" was never referenced
  int foo(struct A *a)
                    ^


"Корректирующий релиз набора компиляторов GCC 4.5.2"
Отправлено Sylvia , 17-Дек-10 21:26 
так что камни не в огород GCC, icc и clang это тоже выполнять не хотят :)

"Корректирующий релиз набора компиляторов GCC 4.5.2"
Отправлено anon2 , 17-Дек-10 23:23 
>>так что камни не в огород GCC, icc и clang это тоже выполнять не хотят :)

Пускай не выполняют - в коде бага.
Проблема в том, что gcc компилирует бажный код в непонятно что без предупреждений.

ЗЫ Sun сс компилирует правильно.


"Корректирующий релиз набора компиляторов GCC 4.5.2"
Отправлено Аноним , 18-Дек-10 02:21 
> Проблема в том, что gcc компилирует бажный код в непонятно что без предупреждений.

Так включите предупреждения про инициализацию переменной самой собой: -Winit-self

И что значит в непонятно что и как можно правильно скомпилировать int *a = a? Это undefined behavior, скажите спасибо что компилятор вам диск не отформатировал увидев такую чушь.


"Корректирующий релиз набора компиляторов GCC 4.5.2"
Отправлено anon2 , 18-Дек-10 18:36 
>> -Winit-self

спасибо за опцию.

>> Это undefined behavior

нет, это ошибка в программе.
Кстати, gcc ее обнаруживает, но только не во вложенном блоке.

$cat y.c
int bar(int k)
{
        int k = k;
        return k;
}

$gcc y.c
y.c : In function 'bar':
y.c :3: error: 'k' redeclared as different kind of symbol
y.c :1: note: previous definition of 'k' was here

$cat z.c
int bar(int k)
{{
        int k = k;
        return k;
}}

$gcc z.c
без ошибок.


"Корректирующий релиз набора компиляторов GCC 4.5.2"
Отправлено bircoph , 18-Дек-10 07:25 
Наконец-то баг с графитом и cairo исправили, молодцы.