collect2: error: ld returned 1 exit status

1. collect2: error: ld returned 1 exit status

Mozart Nascimento Pinho
mozartnp

(usa Ubuntu)

Enviado em 24/04/2016 - 23:39h

Olá,

Sou novo no linux, e atualmente uso o ubuntu.
Estou aprendendo a programar, só que estou com dificuldades no linux. Atualmente estou aprendendo C++, e uso (ou tento usar) o geany. E qualquer linha de comando que monto da esse erro no compilador, "collect2: error: ld returned 1 exit status". O que fazer?

A linha de comando que fiz para testar o programa foi:
#include <iostream>
#include <stdlib.h>

int main(){
std:: cout << "Hello World\n";
system("pause");
return 0;
}

E no compilador aparece:
gcc -Wall -o "Documento sem título" "Documento sem título.cpp" (no diretório: /home/mozart/Área de Trabalho)
/tmp/ccCvl28d.o: na função `main':
Documento sem título.cpp:(.text+0xa): referência indefinida para `std::cout'
Documento sem título.cpp:(.text+0xf): referência indefinida para `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)'
/tmp/ccCvl28d.o: na função `__static_initialization_and_destruction_0(int, int)':
Documento sem título.cpp:(.text+0x47): referência indefinida para `std::ios_base::Init::Init()'
Documento sem título.cpp:(.text+0x56): referência indefinida para `std::ios_base::Init::~Init()'
collect2: error: ld returned 1 exit status
Compilação falhou.

E quando ponho para executar, me da o erro 127.

O que fazer?

Abraços.


  


2. Re: collect2: error: ld returned 1 exit status

Perfil removido
removido

(usa Nenhuma)

Enviado em 24/04/2016 - 23:42h

Eu não uso o Geany, mas essa coisa de colocar iostream com stdlib.h é misturar C com C++.

----------------------------------------------------------------------------------------------------------------
# apt-get purge systemd (não é prá digitar isso!)

Encryption works. Properly implemented strong crypto systems are one of the few things that you can rely on. Unfortunately, endpoint security is so terrifically weak that NSA can frequently find ways around it. — Edward Snowden



3. Re: collect2: error: ld returned 1 exit status

Mozart Nascimento Pinho
mozartnp

(usa Ubuntu)

Enviado em 25/04/2016 - 01:09h

listeiro_037 escreveu:

Eu não uso o Geany, mas essa coisa de colocar iostream com stdlib.h é misturar C com C++.

----------------------------------------------------------------------------------------------------------------
# apt-get purge systemd (não é prá digitar isso!)

Encryption works. Properly implemented strong crypto systems are one of the few things that you can rely on. Unfortunately, endpoint security is so terrifically weak that NSA can frequently find ways around it. — Edward Snowden


Caso eu tire o iostream da erro com o ""std:: cout << "Hello World\n";"" , e se eu tiro stdlib.h da erro com "system("pause");"



4. Re: collect2: error: ld returned 1 exit status

Paulo
paulo1205

(usa Ubuntu)

Enviado em 25/04/2016 - 04:52h

Quando o executável gcc é utilizado para fazer a linkagem, ele só importa por padrão as bibliotecas do C. Utilize o executável g++, que importa as do C++ por padrão.


5. Re: collect2: error: ld returned 1 exit status

Mozart Nascimento Pinho
mozartnp

(usa Ubuntu)

Enviado em 26/04/2016 - 08:10h

paulo1205 escreveu:

Quando o executável gcc é utilizado para fazer a linkagem, ele só importa por padrão as bibliotecas do C. Utilize o executável g++, que importa as do C++ por padrão.


Paulo funcionou, muito obrigado cara.




6. Re: collect2: error: ld returned 1 exit status

Paulo
paulo1205

(usa Ubuntu)

Enviado em 26/04/2016 - 15:04h

Com relação ao que o listeiro_037 disse, não era a causa raiz do problema apontado, mas é realmente procedente.

Quando você for usar uma função da biblioteca padrão do C num programa em C++, você deve preferir a versão em C++ do cabeçalho que declara a função. Então, no caso de system(), cujo cabeçalho em C é <stdlib.h>, em C++ você deve incluir <cstdlib>. Se fosse printf(), você usaria <cstdio> em lugar de <stdio.h>. Se fosse localtime(), você deveria usar <ctime> em vez de <time.h>. E assim também para outros cabeçalhos.

Num compilador como o GCC, essa distinção acaba parecendo quase apenas estética. Outros compiladores podem ser mais pedantes em distinguir coisas só de C, coisas só de C++ e coisas que são compartilhadas. Mas mesmo no GCC, não é realmente uma questão apenas estética.

Entre os recursos do C++ desconhecidos pelo C está o uso de namespaces. Para a biblioteca padrão do C++, as funções e classes fazem inclusive parte de um namespace específico, std. Mas o que fazer com o que vem do C? Pois bem, uma das diferenças entre versão C++ de cada cabeçalho e sua versão original em C é importar os símbolos também para o namespace std. Ou seja: se você incluir <stdio.h>, vai ter ::printf() disponível para uso; com <cstdio>, terá ::printf() e std::printf().

Outra diferença é que a versão com forma C++ dá garantias de que todas as funções procedentes da biblioteca do C aproveitadas diretamente pelo C++ serão declaradas com o modificador “extern "C"”. É possível -- e válido -- que o cabeçalho voltado ao C não tenha essa salvaguarda.

Mais ainda, há funções da biblioteca do C que não são importadas diretamente para o C++, mas sofrem alguma modificação de comportamento. Por exemplo, há funções que se valem do polimorfismo (tanto de sobrecarga de funções quanto de programação genérica) oferecido pelo C++, que não existe em C (ao menos não sem um bocado de “truques sujos”). Assim sendo, é possível a <cstdlib> definir uma função abs() que funciona para qualquer tipo de valor inteiro ou de ponto flutuante, em vez de ter, como em C, funções com nomes distintos para cada um dos tipos inteiros (abs(), labs() e llabs(), respectivamente para int, long e long long) e para cada um dos tipos de ponto flutuante (fabsf(), fabs() (sem sufixo) e fabsl(), para float, double e long double, e que ainda por cima são definidas num cabeçalho diferente, <math.h>). Do mesmo modo, <cmath> usa apenas o nome cos() para calcular cossenos de qualquer tipo de ponto flutuante, em vez de, como em C, recorrer a funções com nomes distintos cosf(), cos() e cosl().

(Versões mais recentes da linguagem C até introduziram um mecanismo (tosco) de programação genérica, que permite selecionar, com base no tipo de dados de uma expressão de controle, diferentes tokens. Associado a macros, esse mecanismo permite ter um mesmo nome aparente de função com vários comportamentos distintos, dependendo dos argumentos. Entretanto esse recurso não é utilizado em <math.h>, mas sim em <tgmath.h>. Não deve causar surpresa que não exista um <ctgmath>.)


7. Re: collect2: error: ld returned 1 exit status

Perfil removido
removido

(usa Nenhuma)

Enviado em 26/04/2016 - 19:53h

http://www.cplusplus.com/reference/ctgmath/

----------------------------------------------------------------------------------------------------------------
# apt-get purge systemd (não é prá digitar isso!)

Encryption works. Properly implemented strong crypto systems are one of the few things that you can rely on. Unfortunately, endpoint security is so terrifically weak that NSA can frequently find ways around it. — Edward Snowden



8. Re: collect2: error: ld returned 1 exit status

Paulo
paulo1205

(usa Ubuntu)

Enviado em 27/04/2016 - 10:56h



Obrigado pela correção. Provavelmente, com o C++11, esse novo header foi introduzido no mundo C++. Antes dele, nem teria como, pois ele surgiu no C, oficialmente, apenas em 1999 (com o padrão ISO/IEC 9899:1999, o C99), e o padrão ISO para o C++ foi anterior a isso, em 1998.

Sem necessariamente querer me justificar, mas justificando-me mesmo assim, note que há ainda sites que dizem a mesma coisa que eu disse. Por exemplo, se você procurar por “tgmath.h” na WIkipedia em Inglês, verá que o artigo que AINDA está lá, cujo texto vem desde 24 de outubro de 2012 (e que não foi escrito por mim), fala literalmente isto (grifos meus):

The C++ language includes native support for function overloading and thus does not provide the tgmath.h header even as a compatibility feature.


Provavelmente tal artigo precisa ser atualizado. Mas o comentário fazia sentido no C++98: não havia como oferecer compatibilidade com algo que ainda não tinha sido inventado.

No meu entendimento, o <ctgmath> não faz muito sentido mesmo em C++11. Eis por quê:

1) O “tg” no nome do cabeçalho vem da abreviação de “type generic”. E embora essa generalidade de tipos fosse uma coisa nova no C99, no C++ já era coisa corriqueira.

2) O <cmath>.já fazia praticamente tudo (se não absolutamente tudo) do que <tgmath.h> supostamente inventou.

3) O padrão corrente do C quando o C++11 foi lançado ainda era o C99 (o C11 saiu somente alguns meses depois do C++11). E o <tgmath.h> do C99 era uma excrecência até para muitos programadores de C (cf. https://web.archive.org/web/20131205042841/http://carolina.mff.cuni.cz/~trmac/blog/2005/the-ugliest-..., http://www.pixelstech.net/article/1324906407-The-ugliest-C-feature%3A-%3Ctgmath-h%3E), pois era um cabeçalho mágico, que alterava o comportamento do compilador, mas que não podia ser escrito com nenhuma das construções sintáticas oferecidas pelo próprio C99, e implicava que cada compilador podia inventar seu próprio conjunto de truques internos para poder implementá-lo.

4) <tgmath.h> permite a invocação de funções variadas com base no tipo dos argumentos, mas não permitia seu uso como ponteiros de função. O código (tosco, mas só para dar uma ideia) abaixo, por exemplo, funciona em C++98 com <cmath>, mas não compila em C com <tgmath.h>, a não ser que eu escolha double como tipo associado à macro MY_FLOAT_TYPE.

#ifdef __cplusplus
#include <cmath>
usign namespace std;
#else
#include <tgmath.h>
#endif

// Eu posso trocar o tipo abaixo para double ou long double a cada compilação
#define MY_FLOAT_TYPE float

MY_FLOAT_TYPE f(int operation, MY_FLOAT_TYPE value){
MY_FLOAT_TYPE (*pf)(MY_FLOAT_TYPE);
switch(operation){
case 1: pf=cos; break;
case 2: pf=sin; break;
case 3: pf=sqrt; break;
default: pf=fabs;
}
return value*pf(value);
}


5) Criar um cabeçalho de compatibilidade vazio (ou que seja um mero apelido para outro) é um desperdício.

6) Se alguém decidir parar para converter um programa de C para C++, que faça uma conversão de verdade, em vez de mera adaptação meia-boca. Mesmo que ele use alguma ferramenta automática de conversão (leia-se “adaptação meia-boca”), a ferramenta certamente será programada de modo a saber que não necessariamente tudo que aparecer como <XXX.h> terá um correspondente na forma <cXXX>. Então a tal ferramenta poderia muito bem saber que o correspondente a <tgmath.h> é <cmath> (ou <cmath> mais <ccomplex>) em vez de <ctgmath>.

7) A comunidade em C até hoje não engoliu bem os movimentos feitos pelo comitê de padronização do C no sentido de introduzir recursos voltados exclusivamente à computação numérica, como de C fosse destinado a suplantar completamente o Fortran (foi por causa desse impulso que apareceu a canhestra <tgmath.h>). O curioso é que essas mudanças só causaram problemas: a comunidade C não gostou, criou incompatibilidades desnecessárias com C++, e a comunidade de computação científica, que seria a grande beneficiária da estratégia, simplesmente a ignorou (i.e. Fortran continuou reinando absoluto, e as iniciativas mais fortes de fazer algo em outras linguagens preferiu C++, Java, Python e linguagens de programação funcionais).


O C11 finalmente introduziu a palavra-chave _Generic, que padronizou uma forma de selecionar tokens com base no tipo de uma expressão de controle (é uma solução horrível, mas pelo menos é algo padronizado). Com isso, <tgmath.h> passou finalmente a poder ser escrito e implementado em C (e com mais um monte de macros, que por si sós já deveriam provocar algum nível de alerta). Mas mesmo isso não resolveu a questão dos ponteiros de função.


Por fim, uma nota que provavelmente expõe um bug do GCC 4.8 (que acompanha o Ubuntu 14.04): seu <ctgmath> inclui apenas <cmath>, não <cmath> mais <ccomplex>, que é o que diz o padrão. Então, cabe ter cuidado com o uso disso.






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts