Anda mengkompilasi dengan opsi -std=c99
.
Ini menonaktifkan beberapa ekstensi GCC non-standar seperti asm
fitur.
Lihat https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html#index-std-112 untuk beberapa dokumentasi (tidak terlalu tepat).
Hapus atau ubah baris set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99")
dari cmakefile Anda jika Anda memerlukan perakitan inline.
Gunakan __asm__
bukannya asm
dengan -std=c99
, atau gunakan -std=gnu99
Dari dokumen GCC https://gcc.gnu.org/onlinedocs/gcc-7.2.0/gcc/Extended-Asm.html
Kata kunci asm adalah ekstensi GNU. Saat menulis kode yang dapat dikompilasi dengan -ansi dan berbagai opsi -std, gunakan
__asm__
bukan asm (lihat Kata Kunci Alternatif).
dan https://gcc.gnu.org/onlinedocs/gcc-7.2.0/gcc/Alternate-Keywords.html#Alternate-Keywords:
-ansi dan berbagai opsi -std menonaktifkan kata kunci tertentu. Hal ini menyebabkan masalah saat Anda ingin menggunakan ekstensi GNU C, atau file header tujuan umum yang seharusnya dapat digunakan oleh semua program, termasuk program ISO C. Kata kunci asm, typeof dan inline tidak tersedia dalam program yang dikompilasi dengan -ansi atau -std (walaupun inline dapat digunakan dalam program yang dikompilasi dengan -std=c99 atau -std=c11). Pembatasan kata kunci ISO C99 hanya tersedia ketika -std=gnu99 (yang pada akhirnya akan menjadi default) atau -std=c99 (atau yang setara -std=iso9899:1999), atau opsi untuk versi standar yang lebih baru, digunakan.
Cara untuk mengatasi masalah ini adalah dengan meletakkan
__
di awal dan akhir setiap kata kunci bermasalah. Misalnya, gunakan__asm__
sebagai ganti asm, dan__inline__
bukannya sebaris.Kompiler C lain tidak akan menerima kata kunci alternatif ini; jika Anda ingin mengkompilasi dengan kompiler lain, Anda dapat menentukan kata kunci alternatif sebagai makro untuk menggantikannya dengan kata kunci biasa. Tampilannya seperti ini:
#ifndef __GNUC__ #define __asm__ asm #endif
-pedantic dan opsi lainnya menyebabkan peringatan untuk banyak ekstensi GNU C. Anda dapat mencegah peringatan tersebut dalam satu ekspresi dengan menulis
__extension__
sebelum ekspresi.__extension__
tidak memiliki efek selain dari ini.
-std=gnu99
mengaktifkan ekstensi GNU seperti asm
, sambil tetap mempertahankan bahasa seperti C99.
Standar C99
GCC berfungsi seperti ini untuk mematuhi standar C99, yang menandai simbol garis bawah ganda sebagai dicadangkan.
Dari draft standar C99 N1256 7.1.3 "Reserved identifiers" 1:
Setiap header mendeklarasikan atau mendefinisikan semua pengidentifikasi yang tercantum dalam subklausa terkait, dan secara opsional mendeklarasikan atau mendefinisikan pengidentifikasi yang tercantum dalam subklausul arah pustaka terkait di masa mendatang dan pengidentifikasi yang selalu dicadangkan baik untuk penggunaan apa pun atau untuk digunakan sebagai pengidentifikasi lingkup file.
- Semua pengenal yang dimulai dengan garis bawah dan huruf besar atau garis bawah lainnya selalu dicadangkan untuk penggunaan apa pun.
Jika tidak, jika asm
telah ditentukan sebelumnya, program legal seperti:
int asm = 0;
akan menjadi ilegal.
Uji program
#include <assert.h>
#include <stdint.h>
int main(void) {
uint32_t io = 0;
__asm__ volatile (
"movl %0, %%eax;"
"inc %%eax;"
"movl %%eax, %0;"
: "+m" (io)
:
: "%eax"
);
assert(io == 1);
}
Diuji pada Ubuntu 17.10, GCC 7.2.
asm
adalah ekstensi gcc, Oleh karena itu Anda tidak dapat menggunakan flag seperti std=c99
atau ansi
Detail selengkapnya di https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html#C-Extensions