头文件中定义的函数的重复符号 [英] duplicate symbol of a function defined in a header file

查看:0
本文介绍了头文件中定义的函数的重复符号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个头文件file_ops.hpp,如下所示

#pragma once

bool systemIsLittleEndian() {
    uint16_t x = 0x0011;
    uint8_t *half_x = (uint8_t *) &x;
    if (*half_x == 0x11)
        return true;
    else
        return false;
}

我最初以为这与实现有关,但事实证明,我只需

就会得到重复的符号
#pragma once

bool systemIsLittleEndian() { return true; }
如果我将其设置为inline,链接器错误就会消失。这不是我想依赖的东西,因为inline是请求而不是保证。

此行为的原因是什么?我不是在处理返回某种类型的单例的情况。

还有其他被标记为

的方法
 bool MY_LIB_EXPORT someFunc();// implemented in `file_ops.cpp`

这些函数是否有某种关联(混合导出函数和"普通旧函数")?显然,我只能将实现移到file_ops.cpp,我对为什么会发生这种情况很感兴趣。

推荐答案

如果我将其设置为内联,链接器错误就会消失。这不是我想依赖的东西,因为内联是请求而不是保证。

可以内联该函数。

即使目标代码不是内联的,只要在不同的翻译单元中不以某种方式更改函数,语言也保证不会导致链接器错误或未定义的行为。

如果您#include数百个.cpp文件中的.hpp,您可能会注意到一些代码膨胀,但程序仍然正确。

此行为的原因是什么?我不是在处理返回某种类型的单例的情况。

#include机制可以方便地减少您必须在具有确切内容的多个文件中手动创建的代码量。最后,#include其他文件的所有翻译单元都会从它们#include的文件中获取代码行。

如果您#includefile_ops.hpp,比如说,file1.cpp和file2.cpp,就好像您有:

file1.cpp:

bool systemIsLittleEndian() {
    uint16_t x = 0x0011;
    uint8_t *half_x = (uint8_t *) &x;
    if (*half_x == 0x11)
        return true;
    else
        return false;
}

file2.cpp:

bool systemIsLittleEndian() {
    uint16_t x = 0x0011;
    uint8_t *half_x = (uint8_t *) &x;
    if (*half_x == 0x11)
        return true;
    else
        return false;
}
当您编译这两个.cpp文件并将它们链接在一起以创建可执行文件时,链接器注意到名为systemIsLittleEndian的函数有两个定义。这是链接器错误的来源。

一个解决方案,不使用inline

您的问题的一个解决方案,不使用inline是:

  1. 在.hpp文件中声明该函数。
  2. 在相应的.cpp文件中定义它..

file_ops.hpp:

bool systemIsLittleEndian(); // Just the declaration.

file_ops.cpp:

#include "file_ops.hpp"

// The definition.
bool systemIsLittleEndian() {
    uint16_t x = 0x0011;
    uint8_t *half_x = (uint8_t *) &x;
    if (*half_x == 0x11)
        return true;
    else
        return false;
}

更新

关于

 bool MY_LIB_EXPORT someFunc();// implemented in `file_ops.cpp`

网上有很多关于。这是Microsoft/Windows的问题。以下是了解它的几个起点。

  1. Exporting from a DLL Using __declspec(dllexport)
  2. Importing into an Application Using __declspec(dllimport)

这篇关于头文件中定义的函数的重复符号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆