GNU/Linux >> Belajar Linux >  >> Linux

kesalahan:'asm' tidak dideklarasikan (penggunaan pertama dalam fungsi ini)

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


Linux
  1. Bagaimana Memperbaiki kesalahan Instalasi Ruby:EC_GROUP_new_curve_GF2m tidak dideklarasikan (penggunaan pertama dalam fungsi ini)?

  2. Panggil ke fungsi yang tidak ditentukan simplexml_load_file() – Kesalahan PHP [Terpecahkan]

  3. Tutorial GPROF – Cara menggunakan Alat Profil GNU GCC Linux

  1. Cara menggunakan fungsi shell baris perintah di Linux

  2. Bagaimana cara menggunakan lokasi di cygwin?

  3. Bagaimana menginterpretasikan data smartctl (smartmon) ini

  1. Kesalahan Ini Tentang Pemula/systemd Dengan Runit?

  2. Kesalahan fatal:Memanggil ke fungsi yang tidak ditentukan curl_init()

  3. Kesalahan C++:Tidur tidak dideklarasikan dalam cakupan ini