В то время, когда корабли^W студия собирает проект, g++ упорно придирается к разным моментам.
Например:
ошибка: нет подходящей функции для вызова ‘EVString::EVString(EVString)’
замечание: претенденты: EVString::EVString(EVString&)
замечание: EVString::EVString(VString)
Разобрался, что EVString::EVString(const EVString&) спасает положение. Но с другой стороны это бред, почему я не могу менять данные?
не получается:
ошибка: некорректное преобразование из ‘int (*)(int, int)’ в ‘void*’
А всего то хотелось получить адрес функции.
И так далее. В основном ошибки, связанные с переводом из одного типа в другой.
Долгая отладка таких, казалось бы простых вещей, которые понимает даже студия (2003 года), создают мнение о гцц, как о тупом компиляторе.
Я так понимаю есть веские основания для всех этих глюков?
Римское правило. Тот, кто говорит, что Это не может быть сделано, никогда не должен мешать тому, кто Это делает.
Осень, ну вы поняли.
Зачем еще один код? А человек?
Здравствуйте, MikelSV, Вы писали:
MSV>В то время, когда корабли^W студия собирает проект, g++ упорно придирается к разным моментам. MSV>Например:
ничего не скажу на приплюснутую часть (потому как не знаю), но вот даже на чистом си гнусь долбит конкретно, заставляя меня избавляться от вредных привычек писать код непонятный для окружающих. например, студия это понимает нормально (потому как все по стандарту): printf("var_a = %x\n", a, b++); а вот гнусь грязно ругается. ага, вот вы уже ругаетесь тоже. а вот не надо трогать мой код в мое отсуствие. хотели убрать отладочную печать для создания релиза? ну так разбирайтесь почему оно перестало работать (хинт: b не предполается выводить на экран, его предполагается увеличить на единицу).
так же гнусю не нравится main(). ему подавай int main(). мелочь, конечно, а как анноит. и я бы не сказал, что объявляя int явно мы избавляемся от ошибок или прививаем себе хороший стиль кодинга. впрочем, к гнусю быстро привыкаешь.
americans fought a war for a freedom. another one to end slavery. so, what do some of them choose to do with their freedom? become slaves.
Здравствуйте, MikelSV, Вы писали:
MSV>Разобрался, что EVString::EVString(const EVString&) спасает положение. Но с другой стороны это бред, почему я не могу менять данные?
Скорее всего, у тебя там скорее всего анонимное выражение. Спроси c-smile'а что он об этом думает
Здравствуйте, MikelSV, Вы писали:
MSV>В то время, когда корабли^W студия собирает проект, g++ упорно придирается к разным моментам. MSV>Например:
MSV>
MSV>ошибка: нет подходящей функции для вызова ‘EVString::EVString(EVString)’
MSV>замечание: претенденты: EVString::EVString(EVString&)
MSV>замечание: EVString::EVString(VString)
MSV>
MSV>Разобрался, что EVString::EVString(const EVString&) спасает положение. Но с другой стороны это бред, почему я не могу менять данные?
Дело тут вот в другом. В данном случае мы имеем дело с копирующими конструкторами, а это отдельная статья. Вот что говорит стандарт о копирующих конструкторах:
12.8/2
A non-template constructor for class X is a copy constructor if its first parameter is of type X&, const X&, volatile X& or const volatile X&, and either there are no other parameters or else all other parameters have default arguments (8.3.6).106) [Example: X::X(const X&) and X::X(X&, int=1) are copy constructors.
12.8/3
A declaration of a constructor for a class X is ill-formed if its first parameter is of type X and either there are no other parameters or else all other parameters have default arguments.
Так что гцц в данном случае прав, и максиммум, в чем его можно упрекнуть, так это в неинформативности сообщения об ошибке. Comeau, например, такой случай диагностирует значительно более четко: error: copy constructor for class "A" may not have a parameter of type "A"
MSV>не получается: MSV> ошибка: некорректное преобразование из ‘int (*)(int, int)’ в ‘void*’ MSV>А всего то хотелось получить адрес функции.
MSV>И так далее. В основном ошибки, связанные с переводом из одного типа в другой. MSV>Долгая отладка таких, казалось бы простых вещей, которые понимает даже студия (2003 года), создают мнение о гцц, как о тупом компиляторе. MSV>Я так понимаю есть веские основания для всех этих глюков?
Основания простые — типовая безопасность. Ведь если тебе действительно приспичит что-то во что-то конвертнуть, ты в большинстве случаев, так ил и иначе, найдешь способ это сделать. А вот тем, что компилятор не дает это сделать "в лоб", он оберегает от случайных ошибок и спасибо ему за это, такие ошибки иногда очень трудно ловятся.
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, MikelSV, Вы писали:
MSV>В то время, когда корабли^W студия собирает проект, g++ упорно придирается к разным моментам.
В то время, когда студия плюёт на стандарт...
MSV>Например:
MSV>
MSV>ошибка: нет подходящей функции для вызова ‘EVString::EVString(EVString)’
MSV>замечание: претенденты: EVString::EVString(EVString&)
MSV>замечание: EVString::EVString(VString)
MSV>
MSV>Разобрался, что EVString::EVString(const EVString&) спасает положение. Но с другой стороны это бред, почему я не могу менять данные?
С другой стороны, это бред — почему это тебе надо менять временный объект?
У конструктора копирования могут быть две сигнатуры: T::T(T const&) — используется в подавляющем большинстве случаев, и T::T(T&) — редкое исключение, непонятно когда нужное.
Стандартное приведение rvalue — к const lvalue, но студия решила, что можно приводить и к неконстантной ссылке.
Заодно, открой для себя mutable — если уж так хочешь что-то менять в константном объекте.
MSV>не получается: MSV> ошибка: некорректное преобразование из ‘int (*)(int, int)’ в ‘void*’ MSV>А всего то хотелось получить адрес функции.
По стандарту (и по здравому смыслу — если глянуть чуть шире, чем flat модель памяти) указатели на данные и указатели на функции не пересекаются. Верхним типом для данных является void*, верхним типом для функций — void(*)(void).
Хочешь хранить адрес функции — приводи к void(*)(). Хочешь получить численное значение — приводи к intptr_t.
Следующий вопрос будет "хочу получить адрес функции-члена", там тебя поджидает сюрприз: sizeof(void(A::*)()) > sizeof(void(*)()).
MSV>И так далее. В основном ошибки, связанные с переводом из одного типа в другой. MSV>Долгая отладка таких, казалось бы простых вещей, которые понимает даже студия (2003 года), создают мнение о гцц, как о тупом компиляторе. MSV>Я так понимаю есть веские основания для всех этих глюков?
Основание одно: стандарт С++. А "даже студия" отягощена плохой наследственностью (как кода компилятора, так и разных существующих библиотек), там хвосты тянутся с достандартных времён ещё.
Здравствуйте, мыщъх, Вы писали:
М>ничего не скажу на приплюснутую часть (потому как не знаю)
В этом плане она строже, чем MS VC++.
[...skip...]
М>printf("var_a = %x\n", a, b++); а вот гнусь грязно ругается. ага, вот вы уже ругаетесь тоже. а вот не надо трогать мой код в мое отсуствие. хотели убрать отладочную печать для создания релиза? ну так разбирайтесь почему оно перестало работать (хинт: b не предполается выводить на экран, его предполагается увеличить на единицу).
М>так же гнусю не нравится main(). ему подавай int main(). мелочь, конечно, а как анноит. и я бы не сказал, что объявляя int явно мы избавляемся от ошибок или прививаем себе хороший стиль кодинга. впрочем, к гнусю быстро привыкаешь.
Смотря с какими флагами собирать.
Просто "gcc file.c" на таком коде:
#include <stdio.h>
main () { // без intint a = 0, b = 0;
printf("var_a = %x\n", a, b++);
}
— выдаёт, естественно, тишину.
Если -Wall поставить, конечно, будет ругаться (warning-ми), но можно поставить только те, которые нужны, исключив:
-Wformat, отвечающий за проверку printf, scanf и т.п.;
-Wreturn-type, отвечающий за ругательство на неявный int;
Правда, многовато может флагов получится, по сравнению с обычным выставлением -Wall.
Здравствуйте, мыщъх, Вы писали:
М>ничего не скажу на приплюснутую часть (потому как не знаю), но вот даже на чистом си гнусь долбит конкретно, заставляя меня избавляться от вредных привычек писать код непонятный для окружающих. например, студия это понимает нормально (потому как все по стандарту): printf("var_a = %x\n", a, b++);
Здравствуйте, Alexey F, Вы писали:
AF>Правда, многовато может флагов получится, по сравнению с обычным выставлением -Wall.
А вот и их список, из документации по gcc 4.4.2:
‘-Wall’ turns on the following warning flags:
-Waddress
-Warray-bounds (only with ‘-O2’) -Wc++0x-compat // для C не поставить — будет безболезненно
-Wchar-subscripts
-Wimplicit-int
-Wimplicit-function-declaration
-Wcomment -Wformat // речь в посте выше шла об этом флаге...
-Wmain (only for C/ObjC and unless ‘-ffreestanding’)
-Wmissing-braces
-Wnonnull
-Wparentheses
-Wpointer-sign
-Wreorder -Wreturn-type // ...и об этом.
-Wsequence-point
-Wsign-compare (only in C++)
-Wstrict-aliasing
-Wstrict-overflow=1
-Wswitch
-Wtrigraphs
-Wuninitialized
-Wunknown-pragmas
-Wunused-function
-Wunused-label
-Wunused-value
-Wunused-variable
-Wvolatile-register-var
Здравствуйте, Alexey F, Вы писали:
AF>Смотря с какими флагами собирать. AF>Если -Wall поставить, конечно, будет ругаться (warning-ми),
с -Wall. но на ключи компиляции я влиять не могу. за них отвечает ведущий разработчик проекта, а я пока же рангом пониже буду и потому мне остается только писать такой код, чтобы не было варнингов. к слову сказать меня изрядно долбает, что конструкции if (!(f=fopen()) так же вызывают матюги компилятора. умом я понимаю, что многие путают = и ==, поэтому компилятор "услужливо" об этом предупреждает. но дробить на две строки эту конструкцию мне упорно не нравится. а если это еще и что-то типа for() if (!(a=max(a, buf[i])) break; то тут у нас получается +3 строки. две из которых фигурные скобки. ну и что:
for()
{
a = max(a, buf[i]);
if (a==0) break;
}
оно конечно легче читается, но ведь и места больше занимает ;(
americans fought a war for a freedom. another one to end slavery. so, what do some of them choose to do with their freedom? become slaves.
[...skip...] М>к слову сказать меня изрядно долбает, что конструкции if (!(f=fopen()) так же вызывают матюги компилятора. умом я понимаю, что многие путают = и ==, поэтому компилятор "услужливо" об этом предупреждает. но дробить на две строки эту конструкцию мне упорно не нравится.
Ругается со скобками (т.е. !(f=fopen())), точно?
Просто у меня на -Wall и -Wextra как раз со скобками (т.е. if ( (...) )) gcc ест и, в случае их отсутствия, даже просит специально поставить — удостовериться, что написано верно:
М>а если это еще и что-то типа for() if (!(a=max(a, buf[i])) break; то тут у нас получается +3 строки. две из которых фигурные скобки. ну и что:
Аналогично, на -Wall и -Wextra собирается без шума.
Толи кроме -Wall ещё какой флаг стоит (хотя не нашёл отдельного флага, чтобы не был включён в -Wall и взводил бы ругань компилятора на такой код вне зависимости от обрамления скобками), толи версия gcc такая —
К>У конструктора копирования могут быть две сигнатуры: T::T(T const&) — используется в подавляющем большинстве случаев, и T::T(T&) — редкое исключение, непонятно когда нужное.
transfer ownership например чтобы сделать... редко (даже крайне редко в моей практике), но полезная фича ...
Здравствуйте, мыщъх, Вы писали:
М>Здравствуйте, MikelSV, Вы писали:
MSV>>В то время, когда корабли^W студия собирает проект, g++ упорно придирается к разным моментам. MSV>>Например:
М>ничего не скажу на приплюснутую часть (потому как не знаю), но вот даже на чистом си гнусь долбит конкретно, заставляя меня избавляться от вредных привычек писать код непонятный для окружающих. например, студия это понимает нормально (потому как все по стандарту): printf("var_a = %x\n", a, b++); а вот гнусь грязно ругается.
gcc наткнулся на паттерн говнокода.
М>ага, вот вы уже ругаетесь тоже.
Конечно мы будем ругаться, т.к. нарушено простое правило — отладочный вывод и прочие assert-ы не должны изменять состояние системы.
М>а вот не надо трогать мой код в мое отсуствие. хотели убрать отладочную печать для создания релиза? ну так разбирайтесь почему оно перестало работать (хинт: b не предполается выводить на экран, его предполагается увеличить на единицу).
Нужно уважать время и труд коллег. Тогда и недоразумений не будет.
М>так же гнусю не нравится main(). ему подавай int main(). мелочь, конечно, а как анноит.
В какой-то версии С стандарта, если не указан тип возвращаемого значения функции, то он int. Может, если скормить gcc один из http://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html#C-Dialect-Options ключей, он ругаться и не будет.
нет подходящей функции для вызова ‘MSL::SetVal(EVString, MString&, MSLKValLine&)’
претенденты: bool MSL::SetVal(EVString&, VString, MSLKValLine&)
bool MSL::SetVal(EVString&, VString)
Это уже не конструктор. гцц не умеет считать количество параметров?
Бред крепчает в:
ошибка: нет подходящей функции для вызова ‘crbil::add(crbi)’
280: замечание: претенденты: void crbil::add(crbi&)
284: замечание: void crbil::add(int, char*)
288: замечание: void crbil::add(int, char*, int, char*)
Возможно я не понимаю смысла '&'?
Мне всегда казалось, что & это тоже самое, что и *, только код выглядит как для обычной переменной.
& это Возможности указателя минус сложности работы с указателем.
Ощущается, что использование const & ограничивает меня в возможностях.
И не очень понятен смысл фразы "временный объект", ввиду того, что этот объект даже более постоянен.
HLString : public LString
в LString есть operator MString().
и вызывается с тонким намеком (MString)lsret;
По идее здесь все логично.
к
class A{
...
bool sendping(crbi &or);
...
};
Пристает с ошибка: expected ‘,’ or ‘...’ before ‘||’ token
вообще не понятно, чего он хочет.
В общем куча ошибок, которые вообще не понятно как лечить, и главное не делать снова.
Римское правило. Тот, кто говорит, что Это не может быть сделано, никогда не должен мешать тому, кто Это делает.
Осень, ну вы поняли.
Зачем еще один код? А человек?
Здравствуйте, Alexey F, Вы писали:
AF>Толи кроме -Wall ещё какой флаг стоит (хотя не нашёл отдельного флага, чтобы не был включён в -Wall и взводил бы ругань компилятора на такой код вне зависимости от обрамления скобками), толи версия gcc такая —
у нас 4.1.х и ругается всегда при -Wall -Wextra -Wformat=...
то есть от количества скобок не зависит. В гугле видел ссылки на гнутый мейл лист где писали что так и задумано.
Здравствуйте, MikelSV, Вы писали:
MSV>Тогда вопрос посложнее: MSV>
MSV>нет подходящей функции для вызова ‘MSL::SetVal(EVString, MString&, MSLKValLine&)’
MSV>претенденты: bool MSL::SetVal(EVString&, VString, MSLKValLine&)
MSV>bool MSL::SetVal(EVString&, VString)
MSV>Это уже не конструктор. гцц не умеет считать количество параметров?
MSV>Бред крепчает в: MSV>
MSV>ошибка: нет подходящей функции для вызова ‘crbil::add(crbi)’
MSV>280: замечание: претенденты: void crbil::add(crbi&)
MSV>284: замечание: void crbil::add(int, char*)
MSV>288: замечание: void crbil::add(int, char*, int, char*)
MSV>Возможно я не понимаю смысла '&'? MSV>Мне всегда казалось, что & это тоже самое, что и *, только код выглядит как для обычной переменной. MSV>& это Возможности указателя минус сложности работы с указателем.
MSV>Ощущается, что использование const & ограничивает меня в возможностях.
MSV>И не очень понятен смысл фразы "временный объект", ввиду того, что этот объект даже более постоянен.
Код вызова покажи — разберемся, че там временное, че постоянное, а че не понравилось компилятору.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Здравствуйте, alsemm, Вы писали:
A>В коде случайно не такое: A>
A>crbil foo;
A>foo.add(crbi());
A>
A>?
Да, это первая операция после объявления переменной.
Код:
cl.add(orb.geto(0));
orb.geto(0) возвращает crbi, так что код в принципе похож.
ЮЖ>'or' — это alternative token, синоним для '||'. Вероятно реализовано через макрос, поэтому сообщение невменяемое.
мда. не догадался. люблю уменьшать названия переменных.
Римское правило. Тот, кто говорит, что Это не может быть сделано, никогда не должен мешать тому, кто Это делает.
Осень, ну вы поняли.
Зачем еще один код? А человек?
Здравствуйте, MikelSV, Вы писали:
A>>В коде случайно не такое: A>>
A>>crbil foo;
A>>foo.add(crbi());
A>>
A>>?
MSV>Да, это первая операция после объявления переменной. MSV>Код: MSV>cl.add(orb.geto(0)); MSV>orb.geto(0) возвращает crbi, так что код в принципе похож.
Это и называется временный объект. VC такое тоже научился запрещать, в полном соответствии со стандартом. Мотивация у стандартизаторов была простая — на кой черт разрешать модифицировать временный объект, если им все равно никто воспользоваться не сможет? Это конечно не всегда оправдано, но уж как сделали — так сделали.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.