2016-03-29 20 views
4

içinde sessiz bir şekilde yok sayılıyor. Ayrı bir işlev kümesini ayrı bir bölüme koymaya çalışıyorum ve GCC ile çalışırken sorun yaşıyorum. Beklediğim gibi clang ilebölüm özniteliği, GCC

namespace /* anonymous */ { 
    [[gnu::section(".mysection")]] 
    void regular_func() { } 

    template <class T> 
    [[gnu::section(".mysection")]] 
    void template_func() { } 
} // namespace /* anonymous */ 

void (*ptr1)() = &regular_func; 
void (*ptr2)() = &template_func<int>; 

, regular_func ve template_func<int> ikisi için de semboller .mysection yerleştirilir.

$ clang++ -std=c++14 a.cpp -c && objdump -t a.o | grep -E "regular|template" 
0000000000000000 l  F .mysection 0000000000000006 _ZN12_GLOBAL__N_112regular_funcEv 
0000000000000010 l  F .mysection 0000000000000006 _ZN12_GLOBAL__N_113template_funcIiEEvv 

Ama GCC ile

, fonksiyon şablonu .mysection yerleştirildi, ancak .text.* bölümünde verilmez.

$ g++ -std=c++14 a.cpp -c && objdump -t a.o | grep -E "regular|template" 
0000000000000000 l  F .mysection 0000000000000007 _ZN12_GLOBAL__N_112regular_funcEv 
0000000000000000 l  F .text 0000000000000007 _ZN12_GLOBAL__N_113template_funcIiEEvv 

Ben clang-3.7.1 ve gcc-5.3.0 kullanıyorum.

gcc'yi şablon örneklenmiş işlevi ayrı bir bölüme yerleştirmeye nasıl zorlayabilirim?

+0

Filed bir hata: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70435 – kukyakya

cevap

1

Küçük konfor olabilir, ama istediğiniz her T için template <class T> void template_func(), bir açık örneklerinin oluşturulmasına section niteliği uygularsanız GCC mecbur edecektir örneği oluşturulacak, örneğin Sonra

namespace /* anonymous */ { 
    [[gnu::section(".mysection")]] 
    void regular_func() { } 

    template <class T> 
    void template_func() { } 

    template [[gnu::section(".mysection")]] void template_func<int>(); 

} // namespace /* anonymous */ 


void (*ptr1)() = &regular_func; 
void (*ptr2)() = &template_func<int>; 

:

$ g++ -std=c++14 a.cpp -c && objdump -C -t a.o | grep -E "regular|template" 
0000000000000000 l  F .mysection 0000000000000007 (anonymous namespace)::regular_func() 
0000000000000007 l  F .mysection 0000000000000007 void (anonymous namespace)::template_func<int>() 

Maalesef clang reddeder:

template [[gnu::section(".mysection")]] void template_func<int>(); 

söyleyerek:

template [[gnu::section(".mysection")]] void template_func<int>(); 
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
error: an attribute list cannot appear here 

böylece her derleyici olması gerekir onun koşullu derleme yoluyla kendi yolu.

Üstelik bu düzeltme nasılsa açıkça örneği değil sahip oldukları herhangi T için instantated edilemez template_func() sağlamalıdır ekledi baş ağrısı getirir.

Sen statik T sen örneklenemez izin türlerinden A,B,C... biri olduğunu fonksiyon şablonun vücudunda öne sürerek bu ulaşabilir. Daha sonra T = D = 0 ile eşleştirilirse, static_assert patlayacaktır; Eğer D için açık bir örnekleme listesine D ekleyip ekleyebilirsiniz:

#include <type_traits> 

template<typename T, typename First> 
constexpr bool is_in() 
{ 
    return std::is_same<T,First>::value; 
} 

template<typename T, typename First, typename Second, typename ...Rest> 
constexpr bool is_in() 
{ 
    return is_in<T,First>() || is_in<T,Second,Rest...>(); 
} 

namespace /* anonymous */ { 
    [[gnu::section(".mysection")]] 
    void regular_func() { } 

    template <class T> 
    void template_func() 
    { 
     static_assert(is_in<T,int,float>(),""); 
    } 

    template [[gnu::section(".mysection")]] void template_func<int>(); 
    template [[gnu::section(".mysection")]] void template_func<float>(); 

} // namespace /* anonymous */ 


void (*ptr1)() = &regular_func; 
void (*ptr2)() = &template_func<int>; 
void (*ptr3)() = &template_func<float>; 
void (*ptr4)() = &template_func<char>; // <-- static_assert fails 
+0

Bu çok ilginç öznitelik açık bir öznitelik için onurlandırılır ancak maalesef bu benim için bir seçenek değildir. Parametreyi örnekte tek tip T olarak basitleştirdim, ancak aslında variadic parametrelerdir, bu yüzden tüm olası kombinasyonlar için elle örnekleyemiyorum. – kukyakya