GCC / C ++ не может связывать библиотеки - PullRequest
0 голосов
/ 20 января 2012

Я только начинающий в C ++. Я пытаюсь создать заголовочный файл header.h, но вывод всегда такой:

/tmp/ccTmZKXX.o: In function `main':
main.c:(.text+0x13): undefined reference to `func'
collect2: ld returned 1 exit status

Не могли бы вы помочь мне понять, правильный ли мой способ использования заголовочного файла? Большое спасибо!

Основной код (main.c):

#include "stdio.h"
#include "func.h"

main() {
    double a = f(2.3);
    printf("a=%f\n", a);
}

, где func.c содержит:

double func (double x) { return x ;}

, где func.h содержит:

double func (double);

И я компилирую с:

gcc -o main main.c

Ответы [ 3 ]

5 голосов
/ 20 января 2012

Здесь есть несколько проблем:

  1. Компилятор C ++ в GCC (GNU Compiler Collection) имеет значение g++, а не gcc;последний - компилятор GNU C.

  2. Код в main.c - это (не очень хорошая) программа на C, а не на C ++.C99 объявил вне закона неявный тип возврата int;C ++ практически никогда не допускал этого.

  3. В вашем вопросе используется функция f;ссылки на вашу ошибку компиляции func.Это означает, что вы не показали нам именно тот код, который пытались скомпилировать.

  4. В стандартах написано #include <stdio.h>;Вы тоже должны.

    #include <stdio.h>
    #include "func.h"
    
    int main()
    {
        double a = func(2.3);
        printf("a=%f\n", a);
    }
    

    NB : Это очень хорошая программа на C, если вы работаете с C99.Ожидается, что в C89 вы вернете значение из main(), а не «упадете с конца».C99 следует C ++ 98 и позволяет падать с конца как эквивалент явного return 0;.Я склонен ставить явное return(0); (обычно с, иногда без, скобками - компиляторы в любом случае не возражают).(Я компилирую C с -Wstrict-prototypes; чтобы получить компиляцию без предупреждений, я пишу int main(void), который также работает с C ++, но void там не нужен.)

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

    #ifndef FUNC_H_INCLUDED
    #define FUNC_H_INCLUDED
    
    extern double func(double a);
    
    #endif /* FUNC_H_INCLUDED */
    

    extern не является обязательным.Я склонен использовать его, но есть многие, кто этого не делает.

  6. Исходный файл, определяющий функцию, должен включать заголовок, чтобы гарантировать, что определение функции соответствует объявлению.Весь код, который использует функцию, должен включать заголовок, чтобы в области видимости был прототип.Эта перекрестная проверка имеет решающее значение для надежности.C ++ требует прототипов в области видимости, прежде чем использовать функцию;он не требует прототипа в области видимости до определения функции (но это хорошая практика).В C настоятельно рекомендуется иметь прототип в области видимости до определения внешней (нестатической) функции.Вы можете использовать -Wmissing-prototypes с кодом C и GCC для выявления таких проблем, но эта опция недопустима для G ++.

    #include "func.h"
    
    double func(double x) { return x; }
    
  7. Поскольку это вопрос C ++, мы могли бы рассмотретьвстраивание функции в шапку.Действительно, C99 также поддерживает функции inline.Тем не менее, мы можем пока игнорировать это.

  8. Поскольку это вопрос C ++, мы могли бы подумать, что использование <stdio.h> не годится, потому что это не безопасно для типов.Возможно, вам лучше использовать <iostream> и др., Не в последнюю очередь потому, что они безопасны от типов.

    #include <iostream>
    #include "func.h"
    
    int main()
    {
        double a = func(2.3);
        std::cout << "a=" << a << std::endl;
    }
    
  9. Для правильной компиляции требуется как основная программа, так и вызываемая ею функция, поэтомувы можете написать:

    g++ -o main main.c func.c
    

    Или, если вы компилируете его в C, то:

    gcc -std=c99 -o main main.c func.c
    

    Обратите внимание, что -std=c99 необходимо для обеспечения отсутствия return в main() допустимо.

    Обратите внимание, что для исходного кода C ++ используется несколько расширений, включая .C, .cpp и .cxx, все из которых принимаются G ++ (такжекак .c).

4 голосов
/ 20 января 2012

Здесь несколько вещей не так.

  1. Определите функцию следующим образом в func.h

    extern double func(double);
    
  2. При компиляции укажите все исходные (c, cpp) файлы

    gcc main.c func.c -o main
    

Тебе должно быть хорошо идти.

1 голос
/ 20 января 2012

Скомпилируйте так:

gcc -o main main.c func.c

Тогда все будет хорошо.

...