Почему невозможно встроить определения функций в файл .cpp? - PullRequest
0 голосов
/ 03 июня 2018

Почему невозможно встроить определения функций функций-членов или классов в файлы .cpp?Например, в моих тестовых примерах ниже компоновщик выдаст мне ошибку неопределенная ссылка , если я попытаюсь встроить определение функции или члена класса в файл cpp:

test.h

void print();

class A
{
    public:
        void print() const;
};

test.cpp

#include <test.h>

inline void print()
{
    // implementation
}

inline void A::print() const
{
    // implementation
}

main.cpp

#include <test.h>

int main(int argc, char** argv)
{
    print(); // undefined reference to `print()'
    A a;
    a.print(); // undefined reference to `A::print() const'

    return 0;
}

Я прочитал ответов здесь , но я все еще не уверен, как это работает.

Ответы [ 3 ]

0 голосов
/ 03 июня 2018

С cppreference.com :

Определение встроенной функции или переменной (начиная с C ++ 17) должно присутствовать в единице перевода, к которой осуществляется доступ (не обязательно до точки доступа).

Ваши функции определены в test.cpp, но вы обращаетесь к ним с main.cpp.

0 голосов
/ 03 июня 2018

В) Почему невозможно встроить определения функций в файле .cpp?

Вы можете встроенных функций в файле cpp.

Чего вы не можете сделать, так это получить доступ к этим inline функциям из другого cpp файла.

встроенная функция должна присутствовать в каждом файле, который ее использует.Вот почему они часто идут в заголовочных файлах, поэтому любой источник, которому нужно его использовать, включает в себя заголовок, содержащий его.

0 голосов
/ 03 июня 2018

Ключевое слово inline действительно сбивает с толку, хотя для этого варианта использования все еще ясно, если вы знаете значение.

inline влияет на требования кода, который должен быть сгенерирован.Более конкретно, он сообщает вашему компилятору, что он не должен предвидеть указатель на функцию для этой функции.Как всегда, разрешено копировать содержимое в вызывающую сторону.Из-за встроенного, оригинальная функция не должна быть создана.Таким образом, у вас нет указателя на функцию в test.o.

В main.o вы вызываете эту функцию.Поэтому он пытается разрешить указатель функции, который не был создан, что вызывает ошибку компоновщика.

Нахождение этих случаев может быть сделано, например, с помощью предупреждения компилятора clang: -Wundefined-inline

РЕДАКТИРОВАТЬ

Будет ли встроенная функция не иметь указатель функции?Нет, вы можете отлично взять адрес этой функции, использовать его и передать.Хотя из-за встроенного символа функции вы не можете полагаться на этот указатель функции, сравнивающий равный по сравнению с другим адресом той же функции.

В этом случае у вас где-то будет указатель на функцию в вашем объектефайл.Однако в этом случае компилятору не требуется указывать правильное искаженное имя, чтобы его можно было использовать из другого модуля компиляции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...