Tanımlama makrosunda Pragma


100

Pragma ifadesini diğer ifadelerle birlikte makroya yerleştirmenin bir yolu var mı?

Şöyle bir şey başarmaya çalışıyorum:

#define DEFINE_DELETE_OBJECT(type)                      \
    void delete_ ## type_(int handle);                  \
    void delete_ ## type(int handle);                                                \
    #pragma weak delete_ ## type_ = delete_ ## type

Varsa, artırma çözümleriyle (dalga için tasarruf edin) sorun yok.


5
Muhtemelen ikisi de değil - #pragmalar, C veya C ++ standartları tarafından tanımlanmamıştır.

Önişlemci, çalıştırmak istediği belirli izin verilen alt komut değil.
Puppy

@DeadMG: C ve C ++ arasında ortak olan pek çok şey var. Ön işleme çoğunlukla yaygın olsa da , hangi dil standardının kullanıldığına (C89, C99, C ++ ve C ++ 0x FCD) bağlı olarak ön işlemenin nasıl belirlendiği konusunda büyük farklılıklar vardır.
James McNellis

2
@James McNellis: Teknik olarak, çoğu C programının C ++ 'ya taşınabilir olması, bu gerçekten ortak işlevselliği sağlamaz, çünkü hiçbir C ++ programcısı bunun büyük çoğunluğunu yapmaz. İki dilin aslında pek ortak noktası yok.
Puppy

Yanıtlar:


116

C99 veya c ++ 0x kullanıyorsanız, pragma operatörü vardır.

_Pragma("argument")

eşdeğer olan

#pragma argument

makrolarda kullanılabilmesi dışında (c99 standardının 6.10.9 bölümüne veya c ++ 0x nihai komite taslağının 16.9'una bakın)

Örneğin,

#define STRINGIFY(a) #a
#define DEFINE_DELETE_OBJECT(type)                      \
    void delete_ ## type ## _(int handle);                  \
    void delete_ ## type(int handle);                   \
    _Pragma( STRINGIFY( weak delete_ ## type ## _ = delete_ ## type) )
DEFINE_DELETE_OBJECT(foo);

ne zaman gcc -Everir

void delete_foo_(int handle); void delete_foo(int handle);
#pragma weak delete_foo_ = delete_foo
 ;

32
Bilginize: MSVC, __pragma()önişlemci operatörüne sahiptir, bu maalesef C99 _Pragma()operatöründen biraz farklıdır (C99'lar bir dizge alır, MSVC bir dizede olmayan belirteçleri alır): msdn.microsoft.com/en-us/library/d9x1s805 .aspx
Michael Burr

15
@MichaelBurr MSVC her zaman farklı olmalı, değil mi?
Thomas

5

_Pragma ("bağımsız değişken") ile yapabileceğiniz güzel bir şey, onu aşağıdaki gibi bazı derleyici sorunları ile uğraşmak için kullanmaktır.

#ifdef _MSC_VER
#define DUMMY_PRAGMA _Pragma("argument")
#else
#define DUMMY_PRAGMA _Pragma("alt argument")
#endif

0

Hayır, bunu yapmanın taşınabilir bir yolu yok. Yine de, #pragma'yı kullanmanın taşınabilir bir yolu yoktur. Bu nedenle, birçok C / C ++ derleyicisi pragma benzeri şeyler yapmak için kendi yöntemlerini tanımlar ve bunlar genellikle makrolara gömülebilir, ancak her derleyicide farklı bir makro tanımına ihtiyacınız vardır. Bu rotaya gitmeye istekliysen, genellikle şöyle şeyler yaparsın:

#if defined(COMPILER_GCC)
#define Weak_b
#define Weak_e __attribute__((weak))
#elif defined(COMPILER_FOO)
#define Weak_b __Is_Weak
#define Weak_e
#endif

#define DEFINE_DELETE_OBJECT(type)                      \
    Weak_b void delete_ ## type_(int handle) Weak_e;    \
    Weak_b void delete_ ## type(int handle)  Weak_e;    

Durumunda onun değil bariz Tanımlamak istediğiniz Weak_bve Weak_eGCC gibi bazı derleyiciler bir tür imza zeyilname gibi nitelikleri ekleyin ve bazı MSC gibi bir önek olarak ekleyin çünkü olarak (veya en azından yaptım yapıları paranteze-ve-sonu başlayacak MSC'yi kullandığımdan beri yıllar geçti). Parantez oluşturma yapılarına sahip olmak, tüm tip imzasını bir derleyici yapısına geçirmeniz gerekse bile her zaman çalışan bir şeyi tanımlamanıza olanak tanır.

Elbette, bunu istediğiniz öznitelikler olmadan bir derleyiciye taşımayı denerseniz, makroları hiçbir şeye genişletmeden ve kodunuzun hala çalışacağını ummaktan başka yapabileceğiniz hiçbir şey yoktur. Tamamen uyarı veya pragmaları optimize etme durumunda, bu muhtemeldir. Diğer durumlarda, o kadar değil.

Oh, ve Weak_b ve Weak_e'yi parametreleri alan makrolar olarak tanımlamanız gerektiğinden şüpheleniyorum, ancak sadece bu örnek için nasıl zayıf bir tanım oluşturacağımı öğrenmek için dokümanları okumaya istekli değildim. Bunu okuyucu için bir alıştırma olarak bırakıyorum.


-3

pragma ifadesini diğer ifadelerle birlikte makroya yerleştirmenin bir yolu var mı?

Hayır, önişlemci deyimlerini ön işlemci deyimlerine koyamazsınız. Bununla birlikte, onu bir inlineişleve koyabilirsiniz . Yine de bu Cetiketi yener .


1
Onu bir satır içi işleve koymak ne işe yarar? Önişlemci yönergeleri, bir işlevi tanıyan her şeyden önce işlenir.

2
C99 inline, ve çoğu büyük C89 uygulamasının bazı varyasyonları vardır.
Chris Lutz

@Chris Yorumunuzun bana yöneltildiğini varsayarsak - amacınız - nedir?

@Neil - Hayır, üzgünüm. @ Sbi'nin son cümlesinde yönetiyordum.
Chris Lutz

1
@Chris: Ah, inlineC ++ 'dan ödünç alınan başka bir şey de! :)
sbi
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.