LINUX.ORG.RU

Почему в пакете могут быть грубые ошибки при компилляции?


0

0

Вот есть программа: http://www-i6.informatik.rwth-aachen.de/web/Software/g2p.html

Я скачиваю и ставлю её на Fedora 12 i686

Там есть установочный скрипт на Питоне, я его запускаю, как написано в ридми:

[root@testbed g2p]# python setup.py install --prefix /opt

и получаю, в конечном итоге,

... gcc -pthread -fno-strict-aliasing -DNDEBUG -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m32 -march=i686 -mtune=atom -fasynchronous-unwind-tables -D_GNU_SOURCE -fPIC -fwrapv -fPIC -DMULTIGRAM_SIZE=2 -I/usr/lib/python2.6/site-packages/numpy/core/include -I/usr/include/python2.6 -c Utility.cc -o build/temp.linux-i686-2.6/Utility.o -fpermissive

Utility.cc: In function ‘int Core::getline(std::istream&, std::string&, std::string)’:

Utility.cc:43: error: ‘EOF’ was not declared in this scope

Utility.cc:48: error: ‘EOF’ was not declared in this scope

error: command 'gcc' failed with exit status 1

То есть, какое-то грубейшее нарушение в коде (символ EOF не определён).

Как такое может быть? Ведь не могли же авторы программы не заметить такую тупую ошибку?

Значит, имеет место какая-то несовместимость среды компилляции.

Вот и вопрос — какая? При каких условиях могут получаться такие грубые ошибки при компилляции?

PS

Вот код на Си++, последняя строка — это строка с ошибкой:

#include «Utility.hh»

#include <algorithm>

#include <cstdlib>

#include <iomanip>

#include <iostream>

#include <string>

using namespace Core;

int Core::getline(std::istream& is, std::string& str, std::string delim) {

int token;

std::string::size_type pos = std::string::npos;

// check if end of stream is reached

if (is.get() == EOF) return EOF;



Последнее исправление: Dims2000 (всего исправлений: 2)

gcc 4.3.5 его собирает

4.4.4 и 4.5.1 - нет
авторы программы пишут что проверяли с GCC 4.1 - 4.3

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

Я тоже пришёл к такому выводу, прочтя вот это: http://www.cyrius.com/journal/gcc

Тогда следующий вопрос: а как мне быть в данной ситуации? Нельзя как-то глобально (но временно) отключить в GCC 4.4 такое поведение?

Код программы я менять не хочу, так как он не мой.

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

это не изменение кода программы, это подключение стандартного заголовка,
в рамках соответствия стандартам новой версии GCC

старые компиляторы на
#include <cstdio>

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

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

сам GCC соответствовать «старым» стандартам не заставить, там заголовки libstdc++ почистили, раньше cstdio цеплялся из других заголовочных файлов, теперь нет, его нужно явно #include из исходников

т.е. только такой (тривиальный) патч

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

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

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

Ставятся несколько версий паралельно (возможность зависит от дистрибутива), потом gcc-версия параметры...

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

у меня несколько версий gcc установлено

например -
export CC=gcc-4.3
export CXX=g++-4.3
python setup.py install --prefix /tmp/test-g2p_cc4.3

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

--prefix
естественно задан такой для теста, для нормальной установки нужен обычно /usr

Sylvia ★★★★★
()

такое бывает, когда явно не включаешь в программу тот заголовок, который нужен. Автор смотрит, что и так компилится, значит всё нормально. Такого быть не должно. Если в стандарте написано, что EOF требует cstdio, значит надо ЯВНО подключить cstdio не надеясь на то, что он включится через какие-то другие заголовки.

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

ну и стандарты они обычно меняются со временем, для GCC 4.3 это не было прописано (или соблюдено), для более поздних версий - приведено к стандарту.

Sylvia ★★★★★
()

>>Вот и вопрос — какая?

каждый c++ компилятор использует свой набор загловков из пути /usr/include/c++ (или аналогичный на твоей системе). Структура этих заголовков может быть разной. В случае g++-4.3, просто например, <string> также включает и <cstdio>, и всё компилится. А в случае g++-4.4, <string> уже не включает <cstdio>, и ни фига не компилится.

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

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

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

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

пакет gcc-config переключает различные версии gcc

у меня оно выгядит так

$ gcc-config -l
 [1] armv4t-softfloat-linux-gnueabi-4.4.1 *

 [2] i486-unknown-linux-uclibc-3.4.6
 [3] i486-unknown-linux-uclibc-3.4.6-hardened
 [4] i486-unknown-linux-uclibc-3.4.6-hardenednopie
 [5] i486-unknown-linux-uclibc-3.4.6-hardenednopiessp
 [6] i486-unknown-linux-uclibc-3.4.6-hardenednossp
 [7] i486-unknown-linux-uclibc-4.4.3
 [8] i486-unknown-linux-uclibc-4.4.4 *

 [9] i686-pc-linux-gnu-3.2.3
 [10] i686-pc-linux-gnu-3.4.6
 [11] i686-pc-linux-gnu-3.4.6-hardened
 [12] i686-pc-linux-gnu-3.4.6-hardenednopie
 [13] i686-pc-linux-gnu-3.4.6-hardenednopiessp
 [14] i686-pc-linux-gnu-3.4.6-hardenednossp
 [15] i686-pc-linux-gnu-4.3.2 *
 [16] mips-unknown-linux-uclibc-4.4.4 *

при этом для каждой архитектуры можно установить свою версию компилятора

# gcc --version
gcc (Gentoo 4.3.2-r3 p1.6, pie-10.1.5) 4.3.2
# gcc-config i686-pc-linux-gnu-3.2.3
 * Switching native-compiler to i686-pc-linux-gnu-3.2.3 ...
# . /etc/profile
# gcc --version
gcc (GCC) 3.2.3 20030422 (Gentoo Linux 1.4 3.2.3-r4, propolice)

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

>пакет gcc-config переключает различные версии gcc

у автора темы Fedora, там навряд ли есть gcc-config как в Gentoo,
в бинарных дистрибутивах обычно ставится с суффиксом , т.е. gcc-4.3 gcc-4.4 и через update-alternatives ставится нужный симлинк
gcc-4.4 -> gcc

хотя можно и через переменные окружения

export CC=gcc-4.3
export CXX=g++-4.3
./configure или что там ) python setup.py

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

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

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

Хотя С++ у нас старичок. Ему многое можно простить.

pathfinder ★★★★
()

>Почему в пакете могут быть грубые ошибки при компилляции?

Я скачиваю и ставлю её на Fedora 12 i686

Я скачиваю

Я скачиваю


Качай больше и не такое будет.

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

anonymous
()
Ответ на: комментарий от alex_custov

>компилятор тут какбэ ни при чём, это баг в программе.

а теперь разверни свою мысль пошире.

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

ИМХО позиция, что это проблема исключительно программиста, а со стороны языка об этих трудностях вообще не надо задумываться, неправильная.

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

В старых версиях gcc при включении некоторых стандартных заголовков идет неявное включение других стандартных заголовков, в том числе stdio.h, отсюда все проблемы. Новые версии gcc подчистили в соответствии со стандартом, соответственно код перестал собираться.

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

>>Не надоело обманывать самого себя?

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

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

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

на всякий пожарный: diff -urN директорий_как_было/ директорий_как_стало/

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

>>Не надоело обманывать самого себя?

А я никого не обманываю.

Ну может с обманом я немного перестарался.

что это компиляторы плохие, а я хороший. И стандарт тоже плохой, а я хороший

Откуда такой максимализм? Если я не согласен с позицией, что проблема исключительно в программисте, то это ещё не означает, что я считаю что проблема исключительно в компиляторе или исключительно в стандарте. Между двумя крайностями есть ещё промежуточные состояния. Проблема с компиляцией возникла не из-за рукожопости программиста, а из-за некоторого «несовершенства языка». Вот только не надо доказывать мне, что С++ «совершенен».

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

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

>>Проблема с компиляцией возникла не из-за рукожопости программиста

Проблема с компиляцией на 99% возникла из-за рукожопости программиста

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

>>что понимание природы этой ошибки никак не защитит тебя, меня или ТС от аналогичных ошибок. Вообще никак

понимание природы этой ошибки защитит тебя, меня или ТС от аналогичных ошибок на 100%

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

>Проблема с компиляцией на 99% возникла из-за рукожопости программиста

Ага. Если у тебя руки растут из нужного места, то значит ошибок ты не совершаешь? Так что ли?

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

>понимание природы этой ошибки защитит тебя, меня или ТС от аналогичных ошибок на 100%

Максимализм. Это не лечится. С обманом я не перестарался. Ты действительно обманываешь самого себя.

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

>>Ага. Если у тебя руки растут из нужного места, то значит ошибок ты не совершаешь? Так что ли?

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

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

>>Максимализм. Это не лечится. С обманом я не перестарался. Ты действительно обманываешь самого себя.

Психологи ITT. Я тебе ещё раз повторяю - понимание природы этой ошибки защитит от аналогичных ошибок на 100%. Если ты до сих пор не знаешь, что каждая функция должна иметь прототип и все литералы должны быть определены, то тут не программы надо писать, а подучить язык. И таких ошибок у тебя не будет никогда. А пока что авторы gcc вынуждены писать документы типа «Porting to GCC 4.3», а то такие Васи сразу начинают плакать, что у них программы не компиляться. Только дело в 100% случаев в самих программах, а не в злобных авторах коварных компиляторов.

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

Я тебе ещё раз повторяю - понимание природы этой ошибки защитит от аналогичных ошибок на 100%

ОК. Вот тебе задача. Данный код точно компилируется на стареньком компиляторе 3.3.2 (я проверял). Надо найти все места, из-за которых в будущем при переходе на более новый компилятор данный код может не скомпилироваться. Естественно все надо проанализировать в уме.

#include <vector>
#include <iterator>
#include <sys/socket.h>

char buf[16] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

int main() 
{
  typedef std::vector<bool> bool_arr;
  bool_arr c;
  std::back_insert_iterator<bool_arr> it = std::back_inserter(c);
  *it = true;
  
  bool need = *(c.begin());
  if(need)
  {
    int s = socket(PF_INET,SOCK_STREAM,0);
  
    struct sockaddr_in* addr;
    addr = (struct sockaddr_in*) malloc(sizeof(struct sockaddr));
    memcpy(addr,buf,16);
    printf("ok\n");
  }
}

P.S. На быдлокод внимания не обращать. В данном случае важен лишь критерий «скомпилируется/не скомпилируется».

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

malloc — #include <cstdlib>

memcpy — #include <cstring>

PF_INET, struct sockaddr_in, SOCK_STREAM — как минимум #include <netinet/in.h>, а лучше ещё и #include <netinet/ip.h>, заменить PF_INET на AF_INET, и включить какой-нибудь зголовок для транспортного уровня.

И ещё мне неясно где дано определение struct sockaddr

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

Так не честно. Понятно, что если всем ЛОРом задачу решать, то ни одна ошибка не ускользнет. Когда один ищет ошибки, то высока вероятность, что что-нибудь он все таки упустит из виду. Тут остался неназванным только один косяк, но он весьма и весьма спорный.

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

> Тут остался неназванным только один косяк, но он весьма и весьма спорный

Не томи уже, назови его.

P.S. А ошибки лучше не допускать сразу, чем потом искать.

anonymous
()
Ответ на: комментарий от Sylvia

>старые компиляторы на

#include <cstdio>


ругаться не должны,


Нифига себе не должны. Это разве не прямое нарушение стандарта языка C ?

c-xp
()
Ответ на: комментарий от c-xp

А если речь идет о с++ , зачем тогда подключать сишный stdio ?
В С++ есть же iostream .

c-xp
()
Ответ на: комментарий от anonymous

Не томи уже, назови его.

Эээ.... Походу я протупил. :(

По идее код:

  typedef std::vector<bool> bool_arr; 
  bool_arr c; 
  std::back_insert_iterator<bool_arr> it = std::back_inserter(c); 
  *it = true; 
мог не скомпилироваться при переходе на C++0x. Но похоже нашли способ как это пофиксить. В общем я поспешил. Надо было больше времени уделить задаче.

Вот ссылка: http://www.open-std.org/JTC1/SC22/WG21/docs/lwg-active.html#1334

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

Я тут немного запутался

std::back_insert_iterator<bool_arr> it = std::back_inserter(c);

Разве здесь есть хотя бы один из

back_insert_iterator<Container>&

operator=(typename Container::const_reference value);

back_insert_iterator<Container>&

operator=(typename Container::value_type&& value);

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

*it = true;

то разве *it имеет тип back_insert_iterator?

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