C++ и linux (частые ошибки новичков при сборке программ на C/C++ в Linux)

Модератор: Модераторы разделов

zl3p
Сообщения: 206
Статус: с диагнозом
ОС: операционная клинической

C++ и linux

Сообщение zl3p »

Код: Выделить всё

#include <stdio.h>
int main()
{
    cout << "1";
    return 0;
}


[root@zx cpp]# g++ -o 1 1.cpp
1.cpp: In function ‘int main()’:
1.cpp:5: error: ‘cout’ was not declared in this scope


не догоняю...
Спасибо сказали:

Аватара пользователя
Red Gremlin
Сообщения: 465
Статус: самоучка
ОС: Rosa 2016 Fresh

Re: C++ и linux

Сообщение Red Gremlin »

#include <iostream.h> вместо <stdio.h>
"В мире есть случайность, есть предопределенность и есть то, что ты планируешь совершить."
Спасибо сказали:

Аватара пользователя
Sparky
Сообщения: 604
Статус: core dumped
ОС: Plan 9

Re: C++ и linux

Сообщение Sparky »

Red Gremlin писал(а):
20.09.2007 11:57
#include <iostream.h> вместо <stdio.h>

Ответ не верный :)
Блог
--------------------

GCS/M/MU/P/IT/E d- s: a- C++(+++) UBL++ P->-- L+++$ E- W+++$ N* o? K? w>--
O M-@ V- PS@ PE+ Y+ PGP+ t 5 X R* tv-->- b++ DI? D>+ G e+(++) h--- r+ y++
Спасибо сказали:

Аватара пользователя
brandy
Сообщения: 41
ОС: Gentoo

Re: C++ и linux

Сообщение brandy »

Код: Выделить всё

#include <iostream>
using namespace std;
int  main()
     {
        cout << "Hello\n";
        return(0);
      }
Спасибо сказали:

Serg79
Сообщения: 153

Re: C++ и linux

Сообщение Serg79 »

Sparky писал(а):
20.09.2007 12:03
Red Gremlin писал(а):
20.09.2007 11:57
#include <iostream.h> вместо <stdio.h>

Ответ не верный :)

Если Вы такой умный то почему же сами тогда не напишете верный ответ.
Спасибо сказали:

Sleeping Daemon
Сообщения: 1450

Re: C++ и linux

Сообщение Sleeping Daemon »

Sparky писал(а):
20.09.2007 12:03
Red Gremlin писал(а):
20.09.2007 11:57
#include <iostream.h> вместо <stdio.h>

Ответ не верный :)

Ответ верный.
Спасибо сказали:

Аватара пользователя
Red Gremlin
Сообщения: 465
Статус: самоучка
ОС: Rosa 2016 Fresh

Re: C++ и linux

Сообщение Red Gremlin »

Sleeping Daemon писал(а):
20.09.2007 13:57
Sparky писал(а):
20.09.2007 12:03

Ответ не верный :)

Ответ верный.

Да, нет он прав. gcc на iostream.h deprecated ругается и советует просто iostream.
"В мире есть случайность, есть предопределенность и есть то, что ты планируешь совершить."
Спасибо сказали:

Аватара пользователя
Sparky
Сообщения: 604
Статус: core dumped
ОС: Plan 9

Re: C++ и linux

Сообщение Sparky »

Red Gremlin писал(а):
20.09.2007 14:04
Да, нет он прав. gcc на iostream.h deprecated ругается и советует просто iostream.

Мало того, необходимо еще указать область видмости std.
Блог
--------------------

GCS/M/MU/P/IT/E d- s: a- C++(+++) UBL++ P->-- L+++$ E- W+++$ N* o? K? w>--
O M-@ V- PS@ PE+ Y+ PGP+ t 5 X R* tv-->- b++ DI? D>+ G e+(++) h--- r+ y++
Спасибо сказали:

Sleeping Daemon
Сообщения: 1450

Re: C++ и linux

Сообщение Sleeping Daemon »

Red Gremlin писал(а):
20.09.2007 14:04
Да, нет он прав. gcc на iostream.h deprecated ругается и советует просто iostream.

Ругаться он может. Но компилит.


Sparky писал(а):
20.09.2007 16:06
Мало того, необходимо еще указать область видмости std.

Если просто iostream - то да, нужно указывать.
Что за новамода? Было всё нормально - теперь дополнительные указания давай компилятору...
Спасибо сказали:

Аватара пользователя
Liksys
Сообщения: 2910

Re: C++ и linux

Сообщение Liksys »

Щас за оверквотинг расстреляю.
Ответ был не верный. Используем следующую конструкцию:

Код: Выделить всё

#include <iostream>
int main()
{
    std::cout << "Hello, C++!" << std::endl;
    return 0;
}
Спасибо сказали:

v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: C++ и linux

Сообщение v04bvs »

Sleeping Daemon писал(а):
20.09.2007 16:36
Что за новамода? Было всё нормально - теперь дополнительные указания давай компилятору...

Ничего себе "было", "новамода", "теперь"!. Это стандарт, принятый 9 лет назад. Года через полтора-два следующий примут, надо идти в ногу со временем!
Спасибо сказали:

zl3p
Сообщения: 206
Статус: с диагнозом
ОС: операционная клинической

Re: C++ и linux

Сообщение zl3p »

Код: Выделить всё

std::cout << "Hello, C++!" << std::endl;

имхо, длиннова-то будет. Я запутался, как же всё же писать. Мы это в школе не проходили. Где эти стандарты описаны вообще?
Спасибо сказали:

Аватара пользователя
brandy
Сообщения: 41
ОС: Gentoo

Re: C++ и linux

Сообщение brandy »

Darth Liksys писал(а):
20.09.2007 17:39
Используем следующую конструкцию:

А чем моя конструкция не понравилась? :)
Спасибо сказали:

sergio
Сообщения: 436
Статус: Интересующийся новичок
ОС: Debian GNU/Linux 4 & 5

Re: C++ и linux

Сообщение sergio »

zl3p писал(а):
20.09.2007 20:28

Код: Выделить всё

std::cout << "Hello, C++!" << std::endl;

имхо, длиннова-то будет. Я запутался, как же всё же писать. Где эти стандарты описаны вообще?


#include <iostream>
using namespace std;
cout << "Blah..."
- это для начинающих

#include <iostream>
std::cout << "Blah..."
-для опытных. :happy:

Стандарты описаны в документах ИСО на англ языке, но они продаются за деньги (на их сайте...).

brandy писал(а):
20.09.2007 20:34
Darth Liksys писал(а):
20.09.2007 17:39
Используем следующую конструкцию:

А чем моя конструкция не понравилась? :)

Тем, что импортирует все имена из std в глобальное пространство, разумеется.
Но ноут, что это неправильно - все же перегиб-с... Это нехороший "ленивый" стиль. Но во всех книжках "для начинающих" пользуют именно его, и для хелловорлдов он не противопоказан...
Debian GNU/Linux 4 -- AMD Athlon64 3000+ / Asus 7600GS -- Gnome
Debian GNU/Linux 5 -- Dell (Vostro) 500 (Celeron M560 / iGM965) -- Gnome
Спасибо сказали:

Аватара пользователя
Liksys
Сообщения: 2910

Re: C++ и linux

Сообщение Liksys »

Если хочется покороче и не импортировать все в кучу, можно делать так:

Код: Выделить всё

using std::cout;
cout << "Hello";

Честно говоря, мне не нравится вот это все с юзингами. Всегда пишу полностью имена. Вроде даже у Бени Дохлострауса про это написано.
Спасибо сказали:

Аватара пользователя
deninok
Сообщения: 585
Статус: Программист С++
ОС: Debian GNU/Linux

Re: C++ и linux

Сообщение deninok »

Где эти стандарты описаны вообще?

Кому интересно, можете просмотреть действующий рабочий черновик (датируемый июнем сего года) стандарта С++ здесь. Он бесплатный. Представление о стандарте этот черновик может дать очень хорошее.
Спасибо сказали:

v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: C++ и linux

Сообщение v04bvs »

zl3p писал(а):
20.09.2007 20:28
Где эти стандарты описаны вообще?


http://anatolix.naumen.ru/Books/Standard?v=z8h

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

pograp
Сообщения: 287
Статус: Родгар БОГ ГНОМОВ
ОС: FreeBSD7&CentOS5.2&Fedora10

Re: C++ и linux

Сообщение pograp »

Sparky писал(а):
20.09.2007 16:06
Red Gremlin писал(а):
20.09.2007 14:04
Да, нет он прав. gcc на iostream.h deprecated ругается и советует просто iostream.

Мало того, необходимо еще указать область видмости std.


На мой опыт, если мы пишем по старому стилю iostream.h то обращение к стандартной библиотеке не нужно, он и так уже обратился, если же пишешь по новому почитай Бьерна Страуструпа using namespace std; или using std::cout; или в теле программы std::cout<<"asdasd"; определитесь со стандартами.

v04bvs писал(а):
21.09.2007 19:46
zl3p писал(а):
20.09.2007 20:28
Где эти стандарты описаны вообще?


http://anatolix.naumen.ru/Books/Standard?v=z8h

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

ссылаюсь на Бьерна Страуструпа Язык С++ последние издание этого года
ignoramus et semper ignorabimus
Спасибо сказали:

netguard
Сообщения: 30

Re: C++ и linux

Сообщение netguard »

2 sergio
#include <iostream>
using namespace std;
cout << "Blah..."
- это для начинающих

#include <iostream>
std::cout << "Blah..."
-для опытных.

Это еще почему ?
Помоему как раз наоборот. Есть единственное железное правило которое нужно соблюдать при использовании namespace, не использовать их в header файлах. Не вижу никакой логики в специальном увелечении обьема исходного кода, когда каждый раз используют std. Особенно раздражает такой код:

Код: Выделить всё

for (std::vector<std::string>::iterator it = ...)

Вместо того что так писать:

Код: Выделить всё

typedef std::vector<std::string> StringArray;
for (StringArray::iterator it = ...)
Спасибо сказали:

Аватара пользователя
diesel
Бывший модератор
Сообщения: 5989
ОС: OS X, openSuSE, ROSA, Debian

Re: C++ и linux

Сообщение diesel »

пространные размышления перенесены вот сюда: Поиски C++ под linux....
Спасибо сказали:

ToyShot
Сообщения: 20
ОС: Debian

Re: C++ и linux

Сообщение ToyShot »

И я задам вопрос. На что ругается компилятор gcc при выполнении элементарной программы?

Код:

main () { printf("Hi"); }


Код:

$ gcc hello.c hello.c: In function ‘main’: hello.c:3: warning: incompatible implicit declaration of built-in function ‘printf’


Все конечно компилируется, но все же...
Спасибо сказали:

Аватара пользователя
Rootlexx
Бывший модератор
Сообщения: 4416
Статус: GNU generation
ОС: Debian GNU/Linux

Re: C++ и linux

Сообщение Rootlexx »

ToyShot писал(а):
01.08.2009 16:56
На что ругается компилятор gcc при выполнении элементарной программы?

На не подключённый stdio.h.
Спасибо сказали:

ToyShot
Сообщения: 20
ОС: Debian

Re: C++ и linux

Сообщение ToyShot »

Спасибо
Спасибо сказали:

Аватара пользователя
Dunris
Сообщения: 295
Статус: ...
ОС: Archlinux

Re: C++ и linux

Сообщение Dunris »

Вот тоже решил припомнить то, что знал о С (вспоминать то особо нечего, кстати). Решил написать простой консольный калькулятор:

Код: Выделить всё

#include <stdio.h>
int main()
{
    int first, second, operation, result;
    printf("Calculator\nWaiting: ");
    scanf("%d%c%d", &first, &operation, &second);
    switch(operation)
    {
        case '*': result=first*second; break;
        case '/': result=first/second; break;
        case '+': result=first+second; break;
        case '-': result=first-second; break;
        default: printf("Error...\n"); break;
    }
    printf("%d\n", result);
    return 0;
}

Когда после компиляции пытаюсь запустить:

Код: Выделить всё

$ gcc calculator.c -o calc
$ ./calc
Calculator
Waiting: 3*7
Error...
-1208356464

То есть проблема, как я понял, в операторе switch... почему то выполняется строчка default, а не *, как ожидалось. Где же косяк? :mellow:
P.S. Это не курсовая, это вообще не по учебе. В нашей школе паскаль то только с этого года, стоит ли про Си говорить...
Спасибо сказали:

Аватара пользователя
Rootlexx
Бывший модератор
Сообщения: 4416
Статус: GNU generation
ОС: Debian GNU/Linux

Re: C++ и linux

Сообщение Rootlexx »

Dunris писал(а):
23.08.2009 00:10
Где же косяк?

Очень просто: у вас переменная operation имеет тип int, но читаете-то вы char, и ожидается в параметрах функции указатель на char. Что же происходит?
Тип int хранится в памяти как последовательность четырёх байтов в порядке little-endian (на архитектуре x86), что означает, что младший байт (содержащий младшие разряды) хранится первым. scanf получает в параметрах указатель на int, то есть адрес области памяти размером 4 байта, но записывает-то она туда char размером 1 байт! Этот байт попадает как раз на младшие разряды, идущие первыми, а остальные оказываются нетронутыми.
Порядок little-endian удобен как раз своей «неявной типизацией»: если у вас в переменной типа int хранится, скажем, число 0x0F, то прочитав достаточное количество байт (в данном случае 1), но не все, можно уже получить это число. Поэтому, по идее, даже при чтении числа, образовавшегося при записи char в младший байт, должно получиться правильное значение. И оно получится, если сразу после scanf() поместить следующую операцию:

Код: Выделить всё

operation &= 0xFF
— то есть взять только младший байт, предположив остальные нулевыми. Так почему при обычном чтении числа int на выходе получается нечто, совершенно не напоминающее исходное число? Догадаться можно, выведя числовое значение переменной operation — чаще всего оно оказывается отрицательным. Что, так как знаковые числа записываются дополнительным кодом, означает, что старший бит равен единице. А так как старший бит (да и байт) не модифицировался в процессе выполнения программы, разумно предположить, что он там такой с самого начала. И действительно, начальное значение переменной operation вами не присваивается. То есть на момент запуска программы там может быть что угодно, и, переписав лишь младший байт числа и не тронув остальные, вы лишь немного изменили его (не более чем на 255). А так как при сравнении переменных типов int и char сравниваются на самом деле их числовые значения, то число типа int читается как int, то есть значащими будут все 4 байта, его составляющие. В трёх из которых расположен «мусор». Вот и всё.
Так что решить вашу проблему можно по-разному: можно использовать для хранения char тип char, можно не забывать присваивать переменным начальные нулевые значения, можно вручную «выцеплять» младшие разряды, игнорируя случайный «мусор» в остальных. Лучше и правильнее всего первый способ. И не советую вот так просто игнорировать предупреждения компилятора, а он говорит своё веское слово насчёт вашей исходной программы.
Спасибо сказали:

Аватара пользователя
Dunris
Сообщения: 295
Статус: ...
ОС: Archlinux

Re: C++ и linux

Сообщение Dunris »

Огромное спасибо за столь развернутый ответ!:) Не думал что тут все так запутано, узнал много нового;)
Решить вашу проблему можно по-разному: можно использовать для хранения char тип char, можно не забывать присваивать переменным начальные нулевые значения, можно вручную «выцеплять» младшие разряды, игнорируя случайный «мусор» в остальных. Лучше и правильнее всего первый способ. И не советую вот так просто игнорировать предупреждения компилятора, а он говорит своё веское слово насчёт вашей исходной программы.

Возможно, я не совсем правильно вызываю gcc (gcc program.c) у меня он съел код совершенно молча...
Насчет второго способа я, вроде бы, понял. Собственно я изначально хотел использовать для хранения тип char, но вот цитата из "Языка программирования С" Кернигана и Ритчи:
Оператор SWITCH (переключатель), вызывает передачу управления к одному из нескольких операторов, в зависимости от значения выражения. Оператор имеет форму "SWITCH (выражение) оператор"
В выражении проводятся обычные арифметические преобразования, но результат должен иметь тип INT.

Да и gcc ругался, когда я использовал "switch(объект типа char)"
Спасибо сказали:

Аватара пользователя
Rootlexx
Бывший модератор
Сообщения: 4416
Статус: GNU generation
ОС: Debian GNU/Linux

Re: C++ и linux

Сообщение Rootlexx »

Dunris писал(а):
23.08.2009 18:57
Возможно, я не совсем правильно вызаваю gcc (gcc program.c) у меня он съел код совершенно молча...

Какая у вас версия GCC?
У меня выводится предупреждение:

Код: Выделить всё

alexey@desktop:~$ gcc -o test{,.c}
test.c: В функции ‘main’:
test.c:7: предупреждение: формат ‘%c’ предполагает тип ‘char *’, но аргумент 3 имеет тип ‘int *’
alexey@desktop:~$ gcc --version
gcc (Ubuntu 4.3.3-5ubuntu4) 4.3.3
Copyright (C) 2008 Free Software Foundation, Inc.
Это свободно распространяемое программное обеспечение. Условия копирования
приведены в исходных текстах. Без гарантии каких-либо качеств, включая
коммерческую ценность и применимость для каких-либо целей.

alexey@desktop:~$

Если же:

Код: Выделить всё

char operation;
— то:

Код: Выделить всё

alexey@desktop:~$ gcc -o test{,.c}
alexey@desktop:~$ ./test
Calculator
Waiting: 3*7
21
alexey@desktop:~$ gcc -Wall -pedantic -o test{,.c}
alexey@desktop:~$
— даже с выводом всех предупреждений и в «педантичном» режиме ничего не выводится.
Выражение в операторе switch должно быть целым, то есть принадлежать одному из целочисленных типов.
Спасибо сказали:

Аватара пользователя
Dunris
Сообщения: 295
Статус: ...
ОС: Archlinux

Re: C++ и linux

Сообщение Dunris »

Rootlexx писал(а):
23.08.2009 20:07
Какая у вас версия GCC?

Код: Выделить всё

koc@desktop ~ $ gcc -v
Используются внутренние спецификации.
Целевая архитектура: i686-pc-linux-gnu
Параметры конфигурации: /var/tmp/portage/sys-devel/gcc-4.3.2-r3/work/gcc-4.3.2/configure --prefix=/usr --bindir=/usr/i686-pc-linux-gnu/gcc-bin/4.3.2 --includedir=/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/include --datadir=/usr/share/gcc-data/i686-pc-linux-gnu/4.3.2 --mandir=/usr/share/gcc-data/i686-pc-linux-gnu/4.3.2/man --infodir=/usr/share/gcc-data/i686-pc-linux-gnu/4.3.2/info --with-gxx-include-dir=/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/include/g++-v4 --host=i686-pc-linux-gnu --build=i686-pc-linux-gnu --disable-altivec --disable-fixed-point --enable-nls --without-included-gettext --with-system-zlib --disable-checking --disable-werror --enable-secureplt --disable-multilib --enable-libmudflap --disable-libssp --enable-libgomp --disable-libgcj --with-arch=i686 --enable-languages=c,c++,treelang,fortran --enable-shared --enable-threads=posix --enable-__cxa_atexit --enable-clocale=gnu --with-bugurl=http://bugs.gentoo.org/ --with-pkgversion='Gentoo 4.3.2-r3 p1.6, pie-10.1.5'
Модель многопотоковости: posix
gcc версия 4.3.2 (Gentoo 4.3.2-r3 p1.6, pie-10.1.5)

Если же:

Код: Выделить всё

char operation;
— то:
[code]alexey@desktop:~$ gcc -o test{,.c}
alexey@desktop:~$ ./test
Calculator
Waiting: 3*7
21

Это я наверное вчера переусердствовал :blush: Сейчас тоже получилось... Скорее всего напутал с указателями.
Все время спотыкаюсь в одном месте. Еще не разобрался где необходимо объявление (например для объекта а) типа char a, а где использовать указатель char * a. Купил книгу "Программирование в Linux", там в основном практические примеры программ. И довольно часто практикуется char * a. Вот и я наверное использовал указатель, поэтому switch ругался...
P.S. а можно, если Вам не трудно, кратко рассказать о разнице в определениях? :blush: Извиняюсь, получается как-то нагловато :blush:
Спасибо сказали:

Аватара пользователя
Rootlexx
Бывший модератор
Сообщения: 4416
Статус: GNU generation
ОС: Debian GNU/Linux

Re: C++ и linux

Сообщение Rootlexx »

Dunris писал(а):
23.08.2009 22:53
P.S. а можно, если Вам не трудно, кратко рассказать о разнице в определениях?

Ох, кратко не получится, да и так, чтобы было понятно, тоже вряд ли :). Да и книгу порекомендовать не могу толком, ибо учил C не по книгам. Просмотрите раздел « Книги и Документация », там вроде было что-то.
Если хотите, свяжитесь со мной в личке, по наличии времени постараюсь объяснить, что будет непонятно.
Спасибо сказали:

Аватара пользователя
Dunris
Сообщения: 295
Статус: ...
ОС: Archlinux

Re: C++ и linux

Сообщение Dunris »

Rootlexx писал(а):
24.08.2009 01:32
Ох, кратко не получится, да и так, чтобы было понятно, тоже вряд ли :) . Да и книгу порекомендовать не могу толком, ибо учил C не по книгам. Просмотрите раздел « Книги и Документация », там вроде было что-то.
Если хотите, свяжитесь со мной в личке, по наличии времени постараюсь объяснить, что будет непонятно.

Большое спасибо :) Поищу в книгах, свяжусь, если совсем ничего не получится;)
Спасибо сказали: