当前位置: 首页 > 知识库问答 >
问题:

我的模板专门化不同于调试版本和发布版本,这是gcc错误吗?

佘修为
2023-03-14

首先,我有一个类的头文件,一个没有定义的专业化声明(来自互联网的代码示例)

$ 猫 foo.h

template<typename T>
class foo{
public:
  static void init(){
      return;
  }

};

template<>  void foo<int>::init();

然后有2个模板专业化的实现文件

$ cat foo_int.cpp 
#include "foo.h"
#include<stdio.h>
template<>
void foo<int>::init(){
    printf("init int foo\n");
}

$ cat foo_float.cpp 
#include "foo.h"
#include<stdio.h>
template<>
void foo<float>::init(){
    printf("init float foo\n");
}

最后我得到了一个主文件

$ cat main.cpp
#include "foo.h"

int main(){
  foo<int>::init();
  foo<float>::init();
}

如果我在没有优化的情况下编译并运行它,它会给出:

g foo_ int。cpp foo_ float。cpp main.cpp

如果我添加优化,那么结果是不同的:

$ g foo _ int . CPP foo _ float . CPP main . CPP-O2

结果是不同的。来自互联网的一些解释说,这是由于gcc实现中“弱符号”的一些内部机制,但我的问题:

>

  • “弱符号”/“强符号”是gcc/g的概念,还是c/c语言规范的一部分。

    如果调试和发布结果不同,我应该说这是gcc / g的错误/问题,关于“弱符号”机制?作为开发人员,我不希望我的调试版本与发布版本的行为不同。

    我尝试了clang,不幸的是同样的错误。对于调试/发布“应该”行为如此不同的C /C,这是否是一个“可接受”的情况?

  • 共有2个答案

    西门高歌
    2023-03-14

    您违反了一个定义规则-您的程序包含foo的两个定义

    一个定义出现在编译单元foo_float.cpp中,另一个出现在编译单元main.cpp中。

    违反一个定义规则意味着未定义的行为——在这种情况下,可能发生的情况是:

    • 关闭优化后,程序生成一个实际的函数调用,链接器碰巧将<code>foo_。cpp在可执行文件中的函数版本
    • 编译<code>main时,启用优化。cpp编译器内联函数-自然,它将内联main。cpp的函数版本
    祁均
    2023-03-14

    语言定义要求您在使用显式专用化之前声明该专用化:

    如果模板、成员模板或类模板的成员是显式专用的,则该专用化应在首次使用该专用化之前声明,该专用化将导致隐式实例化发生,在发生此类使用的每个翻译单元中;无需诊断。[temp.expl.spec]/6.

    没有声明<code>foo的显式专门化

     类似资料:
    • 我正在开发一个android应用程序。我有一个java文件,我想在调试和发布构建类型中不同地使用它。我知道我可以有不同的资源文件用于调试和发布版本。但是对Java文件也可以这样做吗?如何实现这一点?

    • 因此,我正在开发的应用程序似乎工作得很好,它与 一起构建得很好,一切都很花哨,但是当我移动到我的./android目录并点击时,生成的apk与我之前使用的应用程序不同,并且充满了我在调试版本中修复的错误 - 它几乎就像它正在构建我的旧文件一样。 < code>npm cache clear - force之类的似乎并没有什么帮助,删除我在。/android/app/ 其他有类似问题的人发现他们的问

    • 我的谷歌登录非常适合调试变体。但是当我尝试构建发布变体时,它停止工作......我提到了这个答案,但就我而言,我还没有上传到我的应用程序到Play商店。那么在这种情况下,我如何获得新的 sha1 密钥呢?

    • 在SO上回答另一个问题时,我遇到了一个有点可疑的gcc编译器错误。令人不快的片段是 谁的最后一行给出了著名的警告 好友声明'

    • 版本号 采用三位版本号,分别是主版本号、次版本号、修订版本号。例如 5.1.2。 参见: http://semver.org/lang/zh-CN/。 主版本号:主版本号内的所有版本必须相互兼容;与其它主版本号不一定完全兼容,尽量向下兼容。 次版本号:代表新特性增强。版本号越大特性越丰富。 修订版本号:代表BugFix版本。只做bug修复使用,版本号越大越稳定。 版本维护 最多同时维护两个版本。

    • 每次我发布我的应用程序时,我都会将所有url字符串和一些键从测试更改为生产。我这样做的方式就是在发布之前注释掉测试字符串。是否有更好的方法根据生成类型处理字符串?