Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/150.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 共享库的cpp文件中的内联函数_C++_Optimization_Shared Libraries_Inline_Compiler Optimization - Fatal编程技术网

C++ 共享库的cpp文件中的内联函数

C++ 共享库的cpp文件中的内联函数,c++,optimization,shared-libraries,inline,compiler-optimization,C++,Optimization,Shared Libraries,Inline,Compiler Optimization,据我所知,内联函数可以放入头文件以及带有内联关键字的源文件中,默认情况下,编译器会尝试内联在头文件中定义memeber函数 我的问题是关于以下源文件, add.h add.cpp #include <iostream> #include "add.h" inline int Add::add(int a, int b) { std::cout << "FUNC: " << __func__ << std::endl; return

据我所知,内联函数可以放入头文件以及带有内联关键字的源文件中,默认情况下,编译器会尝试内联在头文件中定义memeber函数

我的问题是关于以下源文件, add.h

add.cpp

#include <iostream>
#include "add.h"

inline int Add::add(int a, int b) {
    std::cout << "FUNC: " << __func__ << std::endl;
    return a + b;
}
如果我编译add.cpp和main.cpp

g++ -c add.cpp
g++ -c main.cpp
g++ main.o add.o
它抱怨

main.o: In function `main':
main.cpp:(.text+0x1a): undefined reference to `Add::add(int, int)'
collect2: error: ld returned 1 exit status
查看add.o中的符号

     U __cxa_atexit
                 U __dso_handle
000000000000003d t _GLOBAL__sub_I_add.cpp
0000000000000000 t __static_initialization_and_destruction_0(int, int)
                 U std::ios_base::Init::Init()
                 U std::ios_base::Init::~Init()
0000000000000000 r std::piecewise_construct
0000000000000000 b std::__ioinit
它没有add函数,我认为这是因为该函数是内联在.cpp中的。我的问题是,当我们有共享库时,是否需要在示例中的headers add.h中定义内联函数,以便使用库的示例中的源文件main.cpp在obj创建时内联函数?
在链接时使用-flto没有什么区别,因为add.o中没有函数?

您可以将函数定义放在标题中。如果它是在类定义中定义的,则暗示它是内联的


这个问题有一个很好的答案

您可以将函数定义放在标题中。如果它是在类定义中定义的,则暗示它是内联的


这个问题有一个很好的答案

如果在头文件中定义函数,则包含该头文件的每个源文件都会获得该函数的副本。链接器会投诉存在重复的定义


如果在头文件中定义函数并将其标记为内联,则包含该头文件的每个源文件都会获得该函数的副本,但您已经告诉编译器这没关系,链接器不会抱怨


如果您在源文件中定义了一个函数,并且没有将其标记为内联,则其他源文件中的代码可以看到该函数,这样他们就可以调用该函数


如果在源文件中定义函数并将其标记为内联,则其他源文件中的代码将看不到该函数。这就是这里的问题:Add是在Add.cpp中定义的,并且标记为inline,因此它对main.cpp不可见。您可以删除内联或将定义从add.cpp移动到add.h。如果将其移动到add.h,则可以保持原样并将其放在类定义之后,或者直接将其写入类定义中,而不将其标记为内联


链接器优化与此完全不同。从形式上讲,内联意味着在可以的情况下按行扩展此函数,但编译器通常比您更清楚应该做什么。链接器优化可以内联扩展函数,而不考虑内联关键字和其他文件的可见性。但是代码一开始必须是正确的,因此您必须通过修复代码来解决缺少的符号,而不是通过尝试强制某些链接器优化来解决。如果在头文件中定义函数,则包含该头文件的每个源文件都会获得该函数的副本。链接器会投诉存在重复的定义


如果在头文件中定义函数并将其标记为内联,则包含该头文件的每个源文件都会获得该函数的副本,但您已经告诉编译器这没关系,链接器不会抱怨


如果您在源文件中定义了一个函数,并且没有将其标记为内联,则其他源文件中的代码可以看到该函数,这样他们就可以调用该函数


如果在源文件中定义函数并将其标记为内联,则其他源文件中的代码将看不到该函数。这就是这里的问题:Add是在Add.cpp中定义的,并且标记为inline,因此它对main.cpp不可见。您可以删除内联或将定义从add.cpp移动到add.h。如果将其移动到add.h,则可以保持原样并将其放在类定义之后,或者直接将其写入类定义中,而不将其标记为内联


链接器优化与此完全不同。从形式上讲,内联意味着在可以的情况下按行扩展此函数,但编译器通常比您更清楚应该做什么。链接器优化可以内联扩展函数,而不考虑内联关键字和其他文件的可见性。但是代码一开始必须是正确的,因此您必须通过修复代码来解决缺少的符号,而不是试图强制进行链接器优化。

这就是我现在正在做的,这是我的问题,这是唯一的方法吗?啊,我的错,我必须略过这一部分。在这种情况下,这里有一个类似的问题,有一个很好的解释:感谢链接,我想是的,然后我的问题的第二部分是-flto链接时间优化,可以是一个选项吗?我相信lto只能内联它确定可以内联的正常函数。作为第二个来源,Wikipedia关于内联函数的这段引用似乎表明,使用声明为内联函数的任何编译单元都必须可以使用函数定义。在C++中,需要在使用它的每个模块编译单元中定义一个内联函数,而普通函数必须是
仅在单个模块中定义。否则就不可能独立于所有其他模块编译单个模块。这就是我现在正在做的,这是我的问题,这是唯一的方法吗?啊,我的错,我一定浏览了那部分。在这种情况下,这里有一个类似的问题,有一个很好的解释:感谢链接,我想是的,然后我的问题的第二部分是-flto链接时间优化,可以是一个选项吗?我相信lto只能内联它确定可以内联的正常函数。作为第二个来源,Wikipedia关于内联函数的这段引用似乎表明,使用声明为内联函数的任何编译单元都必须可以使用函数定义。在C++中,需要在使用它的每个模块编译单元中定义一个内联函数,而普通函数必须只在单个模块中定义。否则,就不可能独立于所有其他模块编译单个模块。不,不,不。如果函数是内联的,那么它是内联的。不管函数是在.h头文件还是.cpp源文件中定义的;它是.dll/.so共享库还是.exe可执行文件并不重要。一个警告:您也必须在编译时使用-flto。你试过了吗?不,不,不。如果一个函数是内联的-它是内联的。不管函数是在.h头文件还是.cpp源文件中定义的;它是.dll/.so共享库还是.exe可执行文件并不重要。一个警告:您也必须在编译时使用-flto。你试过了吗?我认为链接器优化是指链接时间优化,它是由编译器执行的,而不是链接器。另外,你提到的内联的形式化定义远不是形式化的。我认为链接器优化是指链接时间优化,它是由编译器执行的,而不是链接器。另外,您提到的内联的正式定义远远不是正式的。
main.o: In function `main':
main.cpp:(.text+0x1a): undefined reference to `Add::add(int, int)'
collect2: error: ld returned 1 exit status
     U __cxa_atexit
                 U __dso_handle
000000000000003d t _GLOBAL__sub_I_add.cpp
0000000000000000 t __static_initialization_and_destruction_0(int, int)
                 U std::ios_base::Init::Init()
                 U std::ios_base::Init::~Init()
0000000000000000 r std::piecewise_construct
0000000000000000 b std::__ioinit