提问人:zeboidlund 提问时间:12/23/2011 最后编辑:A.R.zeboidlund 更新时间:4/15/2021 访问量:4913
LNK2019内联函数的未解决错误
LNK2019 unresolved error for inline function
问:
我不知道为什么会这样。我得到的错误如下:
Error 2 error LNK2019: unresolved external symbol "public: int __thiscall Graphics::GLMatrix::getColumnSize(void)" (?getColumnSize@GLMatrix@Graphics@@QAEHXZ) referenced in function _SDL_main C:\Users\holland\Documents\code\c++\projects\OpenGL_01\OpenGL_01\main.obj
Error 3 error LNK2019: unresolved external symbol "public: int __thiscall Graphics::GLMatrix::getRowSize(void)" (?getRowSize@GLMatrix@Graphics@@QAEHXZ) referenced in function _SDL_main C:\Users\holland\Documents\code\c++\projects\OpenGL_01\OpenGL_01\main.obj
Error 4 error LNK1120: 2 unresolved externals C:\Users\holland\Documents\code\c++\projects\OpenGL_01\Debug\OpenGL_01.exe
未链接的是我的 Matrix 类中的 and 函数。我做错了什么?getRowSize()
getColumnSize()
那么,我在这里做错了什么?我一直在寻找...以各种方式搜索。
守则
头文件:
#ifndef GLMATRIX_H
#define GLMATRIX_H
#pragma once
#include <array>
namespace Graphics {
class GLMatrix
{
public:
GLMatrix(int sizeX, int sizeY);
~GLMatrix();
void allocMatrix();
void addColumnI(int row, int column, long item);
void revertRowsByColumns(); /*changes the formula of r * c to c * r*/
GLMatrix &operator *(float scalar); /*multiply by scalar*/
inline int getRowSize();
inline int getColumnSize();
private:
int _sizeX, _sizeY;
long** _pArray;
};
}
#endif //GLMATRIX_H
源:
#include "GLMatrix.h"
namespace Graphics {
GLMatrix::GLMatrix(int sizeX, int sizeY)
{
_sizeX = sizeX;
_sizeY = sizeY;
}
GLMatrix::~GLMatrix()
{
delete _pArray;
}
void GLMatrix::addColumnI(int row, int column, long item) {
}
inline int GLMatrix::getRowSize() {
return _sizeX;
}
inline int GLMatrix::getColumnSize() {
return _sizeY;
}
void GLMatrix::allocMatrix() {
_pArray = new long*[_sizeX];
for (int i = 0; i < _sizeX; ++i) {
_pArray[i] = new long[_sizeY];
}
}
void GLMatrix::revertRowsByColumns() {
long** columns = new long*[_sizeY];
for (int col = 0; col < _sizeY; ++col) {
columns[col] = new long[_sizeX];
memmove(
columns + col,
_pArray[_sizeX - col],
sizeof(_sizeX) - sizeof(col)
);
}
}
}
主要:
#include <SDL.h>
#include "GLMatrix.h"
int main(int argc, char* argv[]) {
//SDL_Init(SDL_INIT_EVERYTHING);
//matrix test
Graphics::GLMatrix* matrix = new Graphics::GLMatrix(3, 3);
int num_rows = matrix->getRowSize();
int num_columns = matrix->getColumnSize();
for (int row = 0; row < num_rows; ++row) {
}
//SDL_Quit();
delete matrix;
return 0;
}
答:
内联函数必须在头文件中定义。(更具体地说,定义必须在使用它的每个翻译单元中可见。
评论
必须在头文件中声明内联函数的常识已不再正确。几年来,大多数编译器都实现了一种称为链接时间优化 (gcc) 或链接时间代码生成 (VC) 的功能,该功能保存了有关内联函数(以及其他函数)的重要信息,允许链接器将所有目标文件视为“一个大的快乐翻译单元”。因此,链接器可以内联您放入 cpp 文件中的函数。
相关链接: http://msdn.microsoft.com/en-us/library/xbf3tbeh.aspx http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html (搜索 -flto)
编辑:从我之前写的内容中显然没有理解。此功能并非旨在使懒惰的程序员免于在每个翻译单元中声明内联函数。但它确实会给你带来这种可能导致问题的副产品。 务必在头文件中声明内联函数。
评论
1. 翻译单元是单个源文件(在本例中为“源”和“主”)以及包含的文件。
2. 内联函数
C++11, §3.2/3
"[...]内联函数应在使用 ODR 的每个翻译单元中定义。[...]"
§ 7.1.2/4
内联函数应在使用内联函数的每个翻译单元中定义,并且在每种情况下都应具有完全相同的定义(3.2)。[...]
您的“源”翻译单元的定义是 和 。您的“主要”翻译单元没有!这是未定义的行为,因为编译器不需要检查它。getRowSize
getColumnSize
LTCG/LTO
弗拉基米尔的部分回答是正确的。有链接时间优化(或链接时间代码生成)。但它并不能帮助懒惰的程序员保存内联函数的函数定义。
LTCG/LTO 是为了让编译器同时看到所有函数,而编译器又可能决定内联函数,而这些函数在正常情况下是不可见的。声明的函数必须根据定义在使用它们的每个点上对编译器可见。因此,LTCG/LTO 不需要(也不应被滥用)来解决缺失的内联链路错误。inline
只是为了澄清一下:我很清楚这是一个老问题,但还没有正确回答,我只是摔倒了。
我还面临着Visual Studio 2019库中内联函数的链接错误问题。我在 C/C++ 属性的语言选项卡中将属性“删除未引用的代码和数据”设置为“否”并解决了链接错误。
评论