2012-05-09 22 views
12

Yazım yöntemlerinin ortak bir kullanımı, bir değişkenin amacının arkasındaki depolama yapısını yeniden tanımlamaksızın bir değişkenin daha iyi bir fikrini iletmek için bir değişkenin "türünü" etkinleştirmektir. Bununla birlikte, bir seferde bir değişkenler sınıfı için depolama yapısını değiştirmenin bir yolu olarak da yazım hataları görüyorum. ÖrneğinYazılı ve baskı formatı belirteçleri

, I char veya uint64_t için uint32_t kod-baz geçiş

typedef uint32_t my_offset_t 

tanımlar ve tip my_offset_t değişkenleri varsa bir satır değiştirme ve yeniden derlenmesine kadar basittir (I ettik varsayarak printf/scanf hariç olmak üzerehard-coded boyutları yerine, kullanılır.

Biçim belirleyicilerini türüne göre kolay bir şekilde, sarıcı işlevleri printf/scanf, if-elses veya ifdefs olmadan değiştirmenin bir yolu var mı?

Teşekkürler!

İlgilenen herkes için, 32 bit ofsetlerle çalışmak üzere 16 bit'lik bir ofset kullanan bir LKM'yi değiştiriyorum, ancak gerekirse 64 bit (veya başka bir şey!) Ofsetine sahip olmasını istiyorum en az değişiklikle.

cevap

9

Bu zor bir iştir, ancak C99'dan <inttypes.h> ve daha sonra bunu yapmanın yolu gösterilmektedir.

Tanımladığınız her tür için, standart ad alanından kaçınmaya dikkat ederek, kendinize uygun bir 'PRI' ve 'SCN' makroları sağlamanız gerekir.

Örneğin, Proje özel önek olarak XYZ kullanın ve üretebilir:

XYZ_PRIx_my_offset_t 
XYZ_PRId_my_offset_t 
XYZ_PRIX_my_offset_t 
XYZ_PRIu_my_offset_t 
XYZ_PRIo_my_offset_t 

ve SCN eşdeğerleri. Dahası, bunu, baz tipi için eşdeğer makro yönünden bu tanımlarsınız:

#define XYZ_PRIx_my_offset_t PRIx32 
#define XYZ_PRId_my_offset_t PRId32 
#define XYZ_PRIX_my_offset_t PRIX32 
#define XYZ_PRIu_my_offset_t PRIu32 
#define XYZ_PRIo_my_offset_t PRIo32 

senin kodda, XYZ_PRIx_my_offset_t makro kullanarak biçim dizeleri oluşturmak:

printf("Offset: 0x%.8" XYZ_PRIX_my_offset_t "\n", my_offset_value); 

ise Daha sonra her şeyi 64-bit'e değiştirmeniz gerekiyor, yazdığınız ve makro tanımlarını uygun şekilde düzenliyorsunuz ve kodun geri kalanı "değişmeden" kalıyor. Gerçekten dikkatli olursanız, tamamen değişmeden oldukça yakın alabilirsiniz.

Her iki 32-bit ve 64-bit sistemde bir çok uyarıyla birlikte ayarladığınızdan emin olun. GCC, mevcut platformunuzdaki sorunlardan haberdar olmayacaktır, ancak diğer tarafta görünebilir. (Sadece 64-bit temiz, ancak 32-bit için kirli olan bazı kodları tamir ettim, şimdi %d yerine XYZ_PRId_int4 gibi bir makro kullanıyor ve her ikisine de temizliyor.

7

Eğer bakarsanız benim earlier question on inttypes.h sistem tanımlı biçim belirteçleri özel türleri için özel baskı belirteçleri yapmak (#define yoluyla) typedefs uyum içinde nasıl kullanılabileceğini görebilirsiniz.

+0

Teşekkür :) Başka vaka herkes bu sorunun ilgileniyor içinde, daha eksiksiz bir yanıttır çünkü olsa diğerini kabul etti. – Vanwaril

0

Başka bir çözüm, imzalı türler için intmax_t ve imzasız türler için uintmax_t dönüştürmektir. Örneğin: n herhangi imzasız türü ise

printf("%ju\n", (uintmax_t)n); 

düzgün çalışacaktır.

*scanf() işlevleri için geçici bir nesne okumalı ve ardından atamalısınız.

(Bu çalışma zamanı kitaplığı bu özellikleri destekleyen varsayar.) Cevap