LINUX.ORG.RU

Странное поведение компилятора.


0

0

Есть (в той же cinepaint-0.19) вот такой код:

858: size_t size = 0; 859: char* buf; 860: LPGAMMATABLE gamma = cmsBuildGamma(256, 1.0), g; 861: if (info->photomet == PHOTOMETRIC_MINISWHITE) 862: g = cmsReverseGamma(256, gamma); 863: else 864: g = gamma; 865: cmsHPROFILE lp = cmsCreateGrayProfile(cmsD50_xyY(), g);

При компиляции возникает ошибка:

tiff.c: In function `load_image': tiff.c:865: parse error before `lp'

Если закомментировать или вырезать строчки с 860 по 864, то компилируется нормально. Если потом перед объявлением lp вписать еще что-нибудь, например, объявление int aaaa=101; то тоже нормально.

Но вот стоит добавить 'if' и на такой код снова ругается на parse error before 'lp':

char* buf; LPGAMMATABLE gamma = cmsBuildGamma(256, 1.0), g; /*if (info->photomet == PHOTOMETRIC_MINISWHITE) g = cmsReverseGamma(256, gamma); else g = gamma;*/ int aaaa=101; if (aaaa==101) aaaa=102; cmsHPROFILE lp = cmsCreateGrayProfile(cmsD50_xyY(), g);

Помогите понять, что происходит: такое впечатление что компилятор в этом месте не переваривает инструкции условного перехода или я сильно чего-то не знаю в Си. Компилировать с отключенной оптимизацией пробовал - не помогает.


 Прошу прощения, форматирование съехало. Вот верно:

Есть (в той же cinepaint-0.19) вот такой код: 

858: size_t size = 0;
859: char* buf;
860: LPGAMMATABLE gamma = cmsBuildGamma(256, 1.0), g;
861: if (info->photomet == PHOTOMETRIC_MINISWHITE)
862:    g = cmsReverseGamma(256, gamma);
863: else
864:    g = gamma;
865: cmsHPROFILE lp = cmsCreateGrayProfile(cmsD50_xyY(), g); 

При компиляции возникает ошибка: 

tiff.c: In function `load_image':
tiff.c:865: parse error before `lp' 

Если закомментировать или вырезать строчки с 860 по 864,
 то компилируется нормально. Если потом перед объявлением lp
вписать еще что-нибудь, например, объявление int aaaa=101;
то тоже нормально. 

Но вот стоит добавить 'if' и на такой код снова ругается на 
parse error before 'lp': 

char* buf;
LPGAMMATABLE gamma = cmsBuildGamma(256, 1.0), g;
/*if (info->photomet == PHOTOMETRIC_MINISWHITE)
     g = cmsReverseGamma(256, gamma);
else
     g = gamma;*/ 
int aaaa=101;
if (aaaa==101) aaaa=102;
cmsHPROFILE lp = cmsCreateGrayProfile(cmsD50_xyY(), g); 

Помогите понять, что происходит: такое впечатление что
компилятор в этом месте не переваривает инструкции
условного перехода или я сильно чего-то не знаю в Си.
 Компилировать с отключенной оптимизацией пробовал - не помогает.

m_m
() автор топика
Ответ на: комментарий от m_m

Cишный компилятор не умеет компилать C++ код ..

В C обьявлять переменные можно только в начале блока ..

lg ★★
()
Ответ на: комментарий от lg

> В C обьявлять переменные можно только в начале блока ..

В C89 (т.е. gcc2) если быть точным.

Novel ★★★★
()
Ответ на: комментарий от ananas

> можно попробовать к CFLAGS добавить -std=c99 (конечно, если версия gcc имеет поддержку этого стандарта)

Так и поступил. Спасибо. Остальным также спасибо.

Вот только избавившись от одной штуки наскочил на другую. В другом файле есть код:

1350:err = stat (filename, &buf); 1351: 1352:if (err == 0 && (buf.st_mode & S_IFDIR))

Сообщение об ошибке: 'S_IFDIR' undeclared

и это при том, что в начале файла присутствует строчка #include <sys/stat.h>

Да и на функцию stat в 1350 - ой строке возражений у компилятора не было.

m_m
() автор топика
Ответ на: комментарий от m_m

> можно попробовать к CFLAGS добавить -std=c99 (конечно, если версия gcc имеет поддержку этого стандарта)

Так и поступил. Спасибо. Остальным также спасибо. 

Вот только избавившись от одной штуки наскочил на другую. В другом файле есть код: 

1350:err = stat (filename, &buf);
1351:
1352:if (err == 0 && (buf.st_mode & S_IFDIR)) 

Сообщение об ошибке: 'S_IFDIR' undeclared 

и это при том, что в начале файла присутствует строчка #include <sys/stat.h> 

Да и на функцию stat в 1350 - ой строке возражений у компилятора не было.

m_m
() автор топика
Ответ на: комментарий от m_m

Исправил. В этом файле и еще в одном я просто вручную добавил #define на эти константы и все получилось.

Хотелось бы, все-таки знать, у программистов в этом форуме, вы же сталкивались с разными ситуациями: что это за ерунда происходила у меня?

В файле /usr/include/sys/stat.h все константы объявлены коректно.

Строчка #include<sys/stat.h> присутствует, тем более что функция stat() нормально находится. Переопределения в других include нет, потому что компилятор об этом не сообщает, а просто undeclared и свои #define я поместил в самое начало файла.

Так любопытно, что за особенности тут проявились?

m_m
() автор топика
Ответ на: комментарий от m_m

>и это при том, что в начале файла присутствует строчка #include <sys/stat.h> 

должно быть:

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

cvv ★★★★★
()
Ответ на: комментарий от lg

>В C обьявлять переменные можно только в начале блока ..

C какого времени???

сколько я встречался с С я обьявлял переменные где считал нужным и нипомню никаких проблем и не только с гцц

cvv ★★★★★
()
Ответ на: комментарий от cvv

> сколько я встречался с С я обьявлял переменные где считал нужным и нипомню никаких проблем и не только с гцц

объявление переменных где угодно в теле функции появилось только в стандарте c99 (для С). раньше все переменные требовалось объявлять в начале функции.

это в С++ переменные где угодно объявлять можно было.

ananas ★★★★★
()
Ответ на: комментарий от ananas

Хм. возможно я С проги компилил как С++ проги :-?

cvv ★★★★★
()
Ответ на: комментарий от cvv

> должно быть:

Есть там все эти три объявления.

m_m
() автор топика
Ответ на: комментарий от cvv

> ты уверен что у тебя обьявлен cmsHPROFILE???

Объявлен, только в другом файле. Мне тут верно посоветовали: сначала я после комментария от lg переместил объявление переменной lp в начало блока и это помогло, но в других файлах тоже были разные parse error. По совету из комментария от ananas, я добавил -std=c99 в CFLAGS и это решило проблему с переменной "lp" за исключением ругани на undeclared S_IFDIR, а также проблемы в другом моем сообщении: http://www.linux.org.ru/jump-message.jsp?msgid=766422

Там я в файле fromrad.h откорректировал исходники и вместо BYTE, прописал где надо BYTE_ и все стало нормально.

Может кто в курсе: может быть, для каких-то версий и при каких-то опциях компилятор позволяет замещать более новыми определения типов?

m_m
() автор топика
Ответ на: комментарий от cvv

>> В C обьявлять переменные можно только в начале блока ..

> C какого времени???

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

lg ★★
()
Ответ на: комментарий от cvv

>>В C обьявлять переменные можно только в начале блока ..

>C какого времени???

>сколько я встречался с С я обьявлял переменные где считал нужным и нипомню никаких проблем и не только с гцц

>cvv ** (*) (17.01.2005 14:36:16)

Ну, блин, дети подтянулись. Ты еще скажи, что в С всегда можно было объявлять типы передаваемых функции аргументов в самом объявлении функции

int func(int a, double b) ...

Ay49Mihas ★★★★
()
Ответ на: комментарий от m_m

1)Куда подевался мой последний пост???

>> ты уверен что у тебя обьявлен cmsHPROFILE???

>Объявлен, только в другом файле.

Его обьявление должно быть _доступным_ в текущем файле иначе ругань будет именно такой: странная ошибка на ровном месте

>Мне тут верно посоветовали: сначала я после комментария от lg переместил объявление переменной lp в начало блока и это помогло, но в других файлах тоже были разные parse error. По совету из комментария от ananas, я добавил -std=c99 в CFLAGS и это решило проблему с переменной "lp"

Здесь советую вернуть lp назад и ограничится только советами от lg

>за исключением ругани на undeclared S_IFDIR, а также проблемы в другом моем сообщении: http://www.linux.org.ru/jump-message.jsp?msgid=766422

И где только ты такие ошибки берёш???

>Там я в файле fromrad.h откорректировал исходники и вместо BYTE, прописал где надо BYTE_ и все стало нормально.

надо было последовать мудрому совету lg и добавить в CFLAGS -DBYTE=BYTE_

>Может кто в курсе: может быть, для каких-то версий и при каких-то опциях компилятор позволяет замещать более новыми определения типов?

Компилер здеся совсем не причём. Проблема или в том что их несколько или в непонятно в чём.

cvv ★★★★★
()
Ответ на: комментарий от lg

>а про то что в C99 можно обьявлять везде я даже не знал ..

>спасибо ananas за хин

не совсем он прав. в С99 нельзя обявлять переменные:

1)внутри for:

for(int i;;){}

2)внутри switch:

switch(i){case 1:int x=2;break;}

а в с++ так можна

cvv ★★★★★
()
Ответ на: комментарий от cvv

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

lg ★★
()
Ответ на: комментарий от cvv

> 1)Куда подевался мой последний пост???

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

>>> ты уверен что у тебя обьявлен cmsHPROFILE???

>> Объявлен, только в другом файле.

> Его обьявление должно быть _доступным_ в текущем файле иначе ругань будет именно такой: странная ошибка на ровном месте

Да доступен он по цепочке include' ов. Тем более, что -std=c99 эту проблему решило.

> И где только ты такие ошибки берёш???

Программа cinepaint-0.19-0 для покадровой обработки видеофильмов http://prdownloads.sourceforge.net/cinepaint/cinepaint-0.19-0.tar.gz?download

Страница проекта: http://cinepaint.sourceforge.net/

Правда, чувствую может быть, надо поменять компилятор с gcc 2.96 и 3.0.4 на более новые. Но пока обошелся старыми, правда пришлось в двух файлах поправить исходники.

Итог: программу эту я, в конце-концов, успешно откомпилировал и установил. Сейчас изучаю работу с ней.

Правка потребоалась следущая:

1) Запуск ./configure с CFLAGS="-O2 -Wall -std=c99"

2) В файле (сейчас пишу с работы и проги под рукой нет, пути пишу на память и могу немного напутать, но если кто имеет под рукой ее исходники - поймет)

plug-ins/hdr/fromrad.h поменял объявление типа с BYTE на BYTE_, чтобы не конфликтовало с BYTE из библиотеки lcms.

3) В файле app/fileops.c пришлось вручную прописать объявления #define для S_IFDIR и S_IFREG, потому что несмотря на

#include <sys/types.h> #include <sys/stat.h> #include <unistd.h>

функция stat() работает, а вот на констатны компилятор ругается как на undeclared.

Откомпилировалось удачно, хотя и с кучами warning'ов, но программа работает.

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

Как ваше мнение? Может кто-нибудь попробует поставить себе тоже Cinepaint?

m_m
() автор топика
Ответ на: комментарий от lg

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

Возможность писать объявления переменных и типов в почти любых местах не такая уж плохая фича. Вот только можно заморочиться если об этом не знать. :)

Хотя, наверное, для лучшей совместимости надо все-таки c89 использовать.

m_m
() автор топика
Ответ на: комментарий от m_m

> Возможность писать объявления переменных и типов в почти любых местах не такая уж плохая фича. Вот только можно заморочиться если об этом не знать. :)

да, но только бы если это можно было делать действительно _везде_ без исключений, а если надо запоминать исключения - то это фича не только полезная, но и вредная ..

lg ★★
()
Ответ на: комментарий от cvv

> надо было последовать мудрому совету lg и добавить в CFLAGS -DBYTE=BYTE_

Так. Что должен делать такой флаг?

>Может кто в курсе: может быть, для каких-то версий и при каких-то опциях компилятор позволяет замещать более новыми определения типов?

> Компилер здеся совсем не причём. Проблема или в том что их несколько или в непонятно в чём.

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

m_m
() автор топика
Ответ на: комментарий от lg

> а если надо запоминать исключения - то это фича не только полезная, но и вредная ..

Трудно сказать. Помимо расширения c99 есть еще gnu99 с какими-то дополнительными gnu добавками к c99, может быть там нет этих исключение - посмотрю позже.

m_m
() автор топика
Ответ на: комментарий от m_m

>> а если надо запоминать исключения - то это фича не только полезная, но и вредная ..

>Трудно сказать. Помимо расширения c99 есть еще gnu99 с какими-то дополнительными gnu добавками к c99, может быть там нет этих исключение - посмотрю позже.

одно есть точно а второе помечается варнингом

cvv ★★★★★
()
Ответ на: комментарий от m_m

>> надо было последовать мудрому совету lg и добавить в CFLAGS -DBYTE=BYTE_

>Так. Что должен делать такой флаг?

Тоже что ты делал вручную только не правит исходные файлы а как-бы на лету

>>>Может кто в курсе: может быть, для каких-то версий и при каких-то опциях компилятор позволяет замещать более новыми определения типов?

>> Компилер здеся совсем не причём. Проблема или в том что их несколько или в непонятно в чём.

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

Именно так как у тебя: непонятные проблемы на ровном месте. Вообщето реально держать вместе несколько компилеров но если они захотят мирно жить

cvv ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.