@smwikipedia maksud Anda beberapa pragma bertahan? #pragma once is a preprocessor directive but #pragma pack is a compiler directive
Lewis Kelsey
Jawaban:
66
#pragma adalah untuk arahan kompilator yang khusus mesin atau khusus sistem operasi, yaitu ia memberitahu kompilator untuk melakukan sesuatu, mengatur beberapa opsi, mengambil beberapa tindakan, mengganti beberapa default, dll. Yang mungkin atau mungkin tidak berlaku untuk semua mesin dan operasi sistem.
"yang mungkin atau mungkin tidak berlaku untuk semua mesin dan sistem operasi." - dan kompiler berbeda di mesin yang sama. Dan yang mungkin berarti hal yang berbeda pada penyusun yang berbeda.
Steve Jessop
53
#pragma digunakan untuk melakukan sesuatu yang spesifik-implementasi di C, yaitu bersikap pragmatis untuk konteks saat ini daripada dogmatis ideologis.
Yang saya gunakan secara teratur adalah di #pragma pack(1)mana saya mencoba memeras lebih banyak dari ruang memori saya pada solusi yang disematkan, dengan susunan struktur yang jika tidak akan berakhir dengan penyelarasan 8 byte.
Sayang kami belum punya #dogma. Itu akan menyenangkan ;)
@Pacerier, biasanya tidak. Sesuai komentar jalfs, data yang diselaraskan pada batas 4 byte untuk prosesor 32 bit atau batas 8 byte untuk prosesor 64 bit biasanya akan dimuat dan disimpan dalam satu operasi. Data yang selaras pada batas yang lebih kecil akan membutuhkan banyak operasi untuk dimuat atau disimpan. Ini lebih lambat.
SmacL
35
Saya biasanya akan mencoba untuk menghindari penggunaan #pragmas jika memungkinkan, karena mereka sangat bergantung pada kompiler dan tidak portabel. Jika Anda ingin menggunakannya secara portabel, Anda harus mengelilingi setiap pragma dengan pasangan #if/ #endif. GCC melarang penggunaan pragma, dan benar-benar hanya mendukung beberapa di antaranya untuk kompatibilitas dengan kompiler lain; GCC memiliki cara lain untuk melakukan hal yang sama dengan yang digunakan oleh kompiler lain untuk pragma.
Misalnya, berikut cara Anda memastikan bahwa struktur dikemas dengan rapat (yaitu, tidak ada bantalan antar anggota) di MSVC:
Jadi jika saya ingin mengkompilasi kode GCC pada MSVC dan perlu mengemas struktur, bagaimana tepatnya cara melakukannya?
SmacL
2
Untuk gcc, ini struct __attribute__((__packed__)) PackedStructure
Laurent Debricon
#pragma once tidak secara realistis "bergantung pada kompilator dan tidak portabel". Ini didukung pada setiap platform utama dan banyak platform bukan-utama .. en.wikipedia.org/wiki/Pragma_once#Portability
xaxxon
1
Perhatikan bahwa C99 dan C11 keduanya berisi (C11) §6.10.6 Pragma directives dan ¶1 Pragma seperti itu yang tidak dikenali oleh implementasi akan diabaikan. Bahkan C90 mengatakan itu, meskipun itu ada di bagian §6.8.6. (Hal ini membuat GCC tidak patuh jika dijalankan hacksaat menemukan pragma yang tidak dikenali, seperti yang dulu pernah dilakukan - lihat #pragmadan GCC , dll.)
Jonathan Leffler
15
Menempatkan #pragma oncedi bagian atas file header Anda akan memastikan bahwa itu hanya disertakan sekali. Perhatikan bahwa #pragma onceini bukan C99 standar, tetapi didukung oleh sebagian besar kompiler modern.
Alternatifnya adalah dengan menggunakan termasuk penjaga (misalnya #ifndef MY_FILE #define MY_FILE ... #endif /* MY_FILE */)
apa yang saya rasakan adalah #pragmaarahan di mana jika Anda ingin kode menjadi lokasi tertentu. katakan situasi di mana Anda ingin penghitung program membaca dari alamat tertentu di mana ISR ditulis maka Anda dapat menentukan ISR di lokasi itu menggunakan #pragma vector=ADC12_VECTORdan diikuti oleh interrupt rotines name dan deskripsinya
Saran terbaik saya adalah melihat dokumentasi kompiler Anda, karena pragma menurut definisi spesifik-implementasi. Misalnya, dalam proyek yang disematkan saya telah menggunakannya untuk menemukan kode dan data di bagian yang berbeda, atau mendeklarasikan penangan interupsi. yaitu:
#pragma code BANK1
#pragma data BANK2
#pragma INT3 TimerHandler
Semua pragma spesifik untuk implementasi - kecuali pragma #pragma STDC ..., yang distandarisasi di semua platform (selain C99).
Jonathan Leffler
4
Semua jawaban di atas membuat penjelasan yang bagus untuk #pragmatetapi saya ingin menambahkan contoh kecil
Saya hanya ingin menjelaskan simple OpenMP exampleyang menunjukkan beberapa kegunaan #pragmauntuk melakukan tugasnya
OpenMp brieflyadalah implementasi untuk pemrograman paralel memori bersama multi-platform (maka kita dapat mengatakannya machine-specificatau operating-system-specific)
mari kita pergi ke contoh
#include<stdio.h>#include<omp.h>// compile with: /openmpint main(){#pragma omp parallel num_threads(4){int i = omp_get_thread_num();
printf_s("Hello from thread %d\n", i);}}
hasilnya adalah
Hello from thread 0Hello from thread 1Hello from thread 2Hello from thread 3Note that the order of output can vary on different machines.
sekarang izinkan saya memberi tahu Anda apa yang #pragma...
itu memberitahu OS untuk menjalankan beberapa blok kode pada 4 utas
ini hanya salah satu many many applicationsyang dapat Anda lakukan dengan yang kecil#pragma
#pragma startup adalah arahan yang digunakan untuk memanggil suatu fungsi sebelum fungsi utama dan untuk memanggil fungsi lain setelah fungsi utama, misalnya
#pragma startup func1
#pragma exit func2
Di sini, func1berlari sebelum maindan func2sesudahnya.
CATATAN: Kode ini hanya berfungsi di kompiler Turbo-C. Untuk mencapai fungsi ini di GCC, Anda dapat mendeklarasikan func1dan func2menyukai ini:
Singkatnya, #pragmaberi tahu kompiler untuk melakukan sesuatu. Berikut beberapa cara saya menggunakannya:
#pragmabisa digunakan untuk mengabaikan peringatan kompilator. Misalnya, untuk membuat GCC tutup mulut tentang deklarasi fungsi implisit, Anda dapat menulis:
#pragma once, jika ditulis di bagian atas file header, akan menyebabkan file header tersebut dimasukkan sekali. libportablememeriksa pragma setelah dukungan.
#pragma
arahan bertahan dari tahap pra-pemrosesan. Tidak seperti#include
dan#define
.Jawaban:
#pragma
adalah untuk arahan kompilator yang khusus mesin atau khusus sistem operasi, yaitu ia memberitahu kompilator untuk melakukan sesuatu, mengatur beberapa opsi, mengambil beberapa tindakan, mengganti beberapa default, dll. Yang mungkin atau mungkin tidak berlaku untuk semua mesin dan operasi sistem.Lihat msdn untuk info lebih lanjut.
sumber
#pragma
digunakan untuk melakukan sesuatu yang spesifik-implementasi di C, yaitu bersikap pragmatis untuk konteks saat ini daripada dogmatis ideologis.Yang saya gunakan secara teratur adalah di
#pragma pack(1)
mana saya mencoba memeras lebih banyak dari ruang memori saya pada solusi yang disematkan, dengan susunan struktur yang jika tidak akan berakhir dengan penyelarasan 8 byte.Sayang kami belum punya
#dogma
. Itu akan menyenangkan ;)sumber
pragma(1)
meningkatkan kecepatan juga? Lihat stackoverflow.com/questions/3318410/…Saya biasanya akan mencoba untuk menghindari penggunaan #pragmas jika memungkinkan, karena mereka sangat bergantung pada kompiler dan tidak portabel. Jika Anda ingin menggunakannya secara portabel, Anda harus mengelilingi setiap pragma dengan pasangan
#if
/#endif
. GCC melarang penggunaan pragma, dan benar-benar hanya mendukung beberapa di antaranya untuk kompatibilitas dengan kompiler lain; GCC memiliki cara lain untuk melakukan hal yang sama dengan yang digunakan oleh kompiler lain untuk pragma.Misalnya, berikut cara Anda memastikan bahwa struktur dikemas dengan rapat (yaitu, tidak ada bantalan antar anggota) di MSVC:
Berikut cara Anda melakukan hal yang sama di GCC:
Kode GCC lebih portabel, karena jika Anda ingin mengkompilasinya dengan kompiler non-GCC, yang harus Anda lakukan adalah
#define __attribute__(x)
Sedangkan jika Anda ingin mem-port kode MSVC, Anda harus mengelilingi setiap pragma dengan
#if
/#endif
pair. Tidak cantik.sumber
struct __attribute__((__packed__)) PackedStructure
hack
saat menemukan pragma yang tidak dikenali, seperti yang dulu pernah dilakukan - lihat#pragma
dan GCC , dll.)Menempatkan
#pragma once
di bagian atas file header Anda akan memastikan bahwa itu hanya disertakan sekali. Perhatikan bahwa#pragma once
ini bukan C99 standar, tetapi didukung oleh sebagian besar kompiler modern.Alternatifnya adalah dengan menggunakan termasuk penjaga (misalnya
#ifndef MY_FILE #define MY_FILE ... #endif /* MY_FILE */
)sumber
apa yang saya rasakan adalah
#pragma
arahan di mana jika Anda ingin kode menjadi lokasi tertentu. katakan situasi di mana Anda ingin penghitung program membaca dari alamat tertentu di mana ISR ditulis maka Anda dapat menentukan ISR di lokasi itu menggunakan#pragma vector=ADC12_VECTOR
dan diikuti oleh interrupt rotines name dan deskripsinyasumber
Saran terbaik saya adalah melihat dokumentasi kompiler Anda, karena pragma menurut definisi spesifik-implementasi. Misalnya, dalam proyek yang disematkan saya telah menggunakannya untuk menemukan kode dan data di bagian yang berbeda, atau mendeklarasikan penangan interupsi. yaitu:
sumber
Semua jawaban di atas membuat penjelasan yang bagus untuk
#pragma
tetapi saya ingin menambahkan contoh kecilSaya hanya ingin menjelaskan
simple OpenMP example
yang menunjukkan beberapa kegunaan#pragma
untuk melakukan tugasnyamari kita pergi ke contoh
hasilnya adalah
sekarang izinkan saya memberi tahu Anda apa yang
#pragma
...itu memberitahu OS untuk menjalankan beberapa blok kode pada 4 utas
ini hanya salah satu
many many applications
yang dapat Anda lakukan dengan yang kecil#pragma
maaf untuk sampel luarnya
OpenMP
sumber
Ini adalah arahan preprocessor yang dapat digunakan untuk menghidupkan atau mematikan fitur tertentu.
Ini terdiri dari dua jenis
#pragma startup
,#pragma exit
dan#pragma warn
.#pragma startup
memungkinkan kita untuk menentukan fungsi yang dipanggil saat program dimulai.#pragma exit
memungkinkan kita untuk menentukan fungsi yang dipanggil saat keluar dari program.#pragma warn
memberitahu komputer untuk menekan peringatan apapun atau tidak.Banyak
#pragma
gaya lain yang dapat digunakan untuk mengontrol kompilator.sumber
#pragma startup
adalah arahan yang digunakan untuk memanggil suatu fungsi sebelum fungsi utama dan untuk memanggil fungsi lain setelah fungsi utama, misalnyaDi sini,
func1
berlari sebelummain
danfunc2
sesudahnya.CATATAN: Kode ini hanya berfungsi di kompiler Turbo-C. Untuk mencapai fungsi ini di GCC, Anda dapat mendeklarasikan
func1
danfunc2
menyukai ini:sumber
Singkatnya,
#pragma
beri tahu kompiler untuk melakukan sesuatu. Berikut beberapa cara saya menggunakannya:#pragma
bisa digunakan untuk mengabaikan peringatan kompilator. Misalnya, untuk membuat GCC tutup mulut tentang deklarasi fungsi implisit, Anda dapat menulis:Versi lama dari
libportable
melakukan hal ini portable .#pragma once
, jika ditulis di bagian atas file header, akan menyebabkan file header tersebut dimasukkan sekali.libportable
memeriksa pragma setelah dukungan.sumber