SORU
29 EYLÜL 2009, Salı


İki kez C ön işlemci ile bağlamak ve " gibi bir makro;arg genişletmek için nasıl ## _ ## MAKRO"?

Bazı işlevlerin adları böyle bir makro ile belirli bir makro değişken değeri bağımlı olduğu bir program yazmaya çalışıyorum:

#define VARIABLE 3
#define NAME(fun) fun ## _ ## VARIABLE

int NAME(some_function)(int a);

Ne yazık ki, makro 12 ** haline döner

int some_function_VARIABLE(int a);

yerine

int some_function_3(int a);

bu açıkça bu konuda gitmek için yanlış bir yoldur. Neyse ki, çok sayıda farklı değer için DEĞİŞKEN küçük yani ben sadece bir #if VARIABLE == n ve liste tüm durumlar ayrı ayrı, ama merak ediyordum da bir zeki var.

CEVAP
29 EYLÜL 2009, Salı


$ cat xx.c
#define VARIABLE 3
#define PASTER(x,y) x ## _ ## y
#define EVALUATOR(x,y)  PASTER(x,y)
#define NAME(fun) EVALUATOR(fun, VARIABLE)

extern void NAME(mine)(char *x);
$ gcc -E xx.c
# 1 "xx.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "xx.c"





extern void mine_3(char *x);
$

Bu yönlendirme iki düzeyde ihtiyacı varCade Roux asked . Küstahça cevap veren standart çalışma gerektirir çünkü; eşdeğer stringizing operatörü ile hile de bulmak eğilimindedir.

C99 standardı bölüm 6.10.3 kapsar 'makro değiştirme' ve 6.10.3.1 'argümanı yerine koyma' kapsar.

İşlevi bir makro çağırma için argümanlar tespit edilmiştir,sonra değişken değiştirme gerçekleşir. Öncesinde sürece yedek listesindeki bir parametre, # ## ön veya ## bir ön belirteci (aşağıya bakınız) İle token ardından, tüm makrolar içerdiği sonra karşılık gelen bağımsız değişken yerine genişletti. İkame edilmeden önce, her tartışma ön belirteçleri vardır tamamen makro eğer önişleme dosyanın geri kalanını oluşturdular olarak değiştirildi; diğer ön belirteçleri kullanılabilir.

Çağırma NAME(mine), argüman 'benim'; tamamen genişletilmiş 'benim', sonra yerine yerini değiştirme dizesi içine:

EVALUATOR(mine, VARIABLE)

Şimdi makro DEĞERLENDİRİCİSİ keşfetti ve bağımsız olarak yalıtılmış 'benim' ve '; ikincisi, sonra tamamen genişletilir' '3', ve yedek dizeye yerine: . DEĞİŞKEN

PASTER(mine, 3)

Bu işlemi diğer hükümlere tabidir ('## operatörü'): . 6.10.3.3

İşleve gibi bir makro yedek listesinde bir parametre hemen öncesinde ise ya ## bir ön belirteci ardından, parametre karşılık gelen değiştirilir tartışma önişleme simge sırası; [...]

Hem de yedek listesi önce-gibi nesne ve fonksiyon gibi makro çağırmaları için yerine daha makro adları için ## bir önişleme her örneği token yeniden incelendi yedek liste (bir değişken) silinir ve önceki ön token aşağıdaki önişleme token ile birleştirilmiş.

O yüzden yedek listesi x ## ## y; var ardından da izledi içerir:

mine ## _ ## 3

ve ## belirteçleri ortadan kaldırılması ve iki tarafında simgeleri bitiştirmek birleştirir 'benim' ' _ ' ve '3' verim için:

mine_3

Bu istenen sonucu.


Eğer asıl soruya bakarsak, kod (kullanmak için adapte 'benim' yerine '') some_function:

#define VARIABLE 3
#define NAME(fun) fun ## _ ## VARIABLE

NAME(mine)

ADI bağımsız değişkeni açıkça 'benim' ve tamamen genişletilir.
6.10.3.3, biz kuralları bulmak aşağıdaki:

mine ## _ ## VARIABLE

## operatörler ortadan kalkar ne zaman, hangi haritalar:

mine_VARIABLE

soruyu tam olarak bildirdi.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • B3ASTTY™

    B3ASTTY™

    27 Mayıs 2013
  • hockeywebcasts

    hockeywebcas

    31 EKİM 2012
  • NikkoNantone

    NikkoNantone

    21 Kasım 2011