我对我最近尝试过的事感到疑惑。这不是生产代码,只是我一起扔的东西,并得到一些我无法解释的奇怪行为。也许有更多C ++经验的人知道发生了什么。
我有一个包含一个类的头文件,里面有实现(暗示编译器要内联它,我猜)。我把这个头文件包含在多个编译成dll的cpp文件中;然后我尝试在多个cpp文件中使用相同的头文件,这些文件编译为lib(静态库)。
由于我不需要进入的原因,我无法在该lib的头文件中使用std的getcurrentthreadid()API(但编译/链接dll时编译时没有问题的相同API) 。所以。只是想解决这个问题(我知道这不是一个好的做法,但想要实验),我复制粘贴了原始的头文件,我删除了对threadid API的特定调用,只是硬编码-1而不是使用类型的方法。
所以现在我有一个由cpps构建的dll,包括带有threadid调用的.h文件,以及来自cpps的lib构建,包括一个几乎相同的.h文件,其中硬编码的id = -1。 dll引用lib文件。
现在,据我所知,在编译lib时,标头内容会在预编译期间被注入cpp文件,然后进行编译。这意味着lib文件应该包含具有硬编码-1的对象代码。 当我编译dll时,另一个头文件被注入cpp文件,并编译cpp代码。然后,在链接期间,lib被加载到dll中。
所以我希望在运行时,来自lib的代码使用硬编码的-1,以及来自dll的代码来使用实际的threadid。但令我惊讶的是,他们似乎都使用了实际的线程。即使在编译lib时,它也抱怨了threadid。
那么,我是否遗漏了所有这些内容?我知道我在做什么并不是好的做法,但对结果感到惊讶。 感谢。
答案 0 :(得分:0)
您的程序通过违反One definition rule:
的方式展示未定义的行为[basic.def.odr] / 6 在程序中可以有多个具有外部链接的内联函数的定义......如果每个定义出现在不同的翻译中单位,并提供定义满足以下要求。鉴于在多个翻译单元中定义了名为
D
的实体,那么(6.1) -
D
的每个定义应由相同的令牌序列组成;和...
实际上,典型的实现会让编译器将函数的编译体发送到使用它的每个目标文件中,并指示链接器选择一个 - 任何一个 - 并丢弃其余的(假设它们是所有相同的。)