簡體   English   中英

我的模板專業化調試版本與發布版本不同,這是gcc的錯誤嗎?

[英]My template specialization differs debug version from release version, is this gcc bug?

首先,我有一個類的頭文件,一個沒有定義的專門化聲明(來自互聯網的代碼示例)

$ cat 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 && a.out
init int foo
init float foo

如果我添加優化,那么結果是不同的:

$ g ++ foo_int.cpp foo_float.cpp main.cpp -O2 && a.out
init int foo

結果是不同的。 互聯網的一些解釋說這是由於gcc實現中“弱符號”的一些內部機制,但我的問題是:

  1. “弱符號”/“強符號”是gcc / g ++的概念,還是c / c ++語言規范的一部分。

  2. 如果調試和發布結果不同,我應該說這是gcc / g ++的錯誤/問題,關於“弱符號”機制? 作為開發人員,我不希望我的調試版本與發布版本的行為不同。

我試過鏗鏘,不幸的是同樣的錯誤。 這是C / C ++的“可接受”情況,調試/發布“應該”表現得如此不同嗎?

語言定義要求在使用之前聲明顯式特化:

如果模板,成員模板或類模板的成員被明確專門化,則應在首次使用該特化之前聲明該特化,這將導致發生隱式實例化,在發生此類使用的每個翻譯單元中; 無需診斷。 [temp.expl.spec] / 6。

在從main調用它時,沒有聲明foo<float>::init()的顯式特化,但是在foo_float.cpp有一個顯式的foo_float.cpp ,所以程序的行為是未定義的。

您違反了一個定義規則 - 您的程序包含兩個 foo<float>::init定義。

一個定義出現在編譯單元foo_float.cpp ,另一個定義出現在編譯單元main.cpp

違反一個定義規則意味着未定義的行為 - 在這種情況下,可能發生的事情是:

  • 關閉優化后,程序會生成一個實際的函數調用,並且鏈接器恰好將foo_float.cpp的函數版本放在可執行文件中。
  • 通過優化,在編譯main.cpp ,編譯器內聯函數 - 當然,它將內聯main.cpp的函數版本。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM