Secara tradisional, cara standar dan portabel untuk menghindari beberapa inklusi header dalam C ++ adalah / adalah dengan menggunakan #ifndef - #define - #endif
skema arahan pra-kompiler juga disebut skema penjaga makro (lihat cuplikan kode di bawah).
#ifndef MY_HEADER_HPP
#define MY_HEADER_HPP
...
#endif
Di sebagian besar implementasi / kompiler (lihat gambar di bawah), ada alternatif yang lebih "elegan" yang memiliki tujuan yang sama dengan skema penjaga makro yang disebut #pragma once
. #pragma once
memiliki beberapa keunggulan dibandingkan dengan skema penjaga makro, termasuk lebih sedikit kode, menghindari bentrokan nama, dan kadang-kadang meningkatkan kecepatan kompilasi.
Melakukan penelitian, saya menyadari bahwa meskipun #pragma once
direktif didukung oleh hampir semua kompiler yang dikenal, ada keruh pada apakah #pragma once
direktif merupakan bagian dari standar C ++ 11 atau tidak.
Pertanyaan:
- Bisakah seseorang mengklarifikasi apakah
#pragma once
arahan merupakan bagian dari standar C ++ 11 atau tidak? - Jika itu bukan bagian dari standar C ++ 11, apakah ada rencana untuk memasukkannya pada rilis nanti (mis., C ++ 14 atau lebih baru)?
- Akan lebih baik jika seseorang dapat menguraikan lebih lanjut tentang kelebihan / kekurangan dalam menggunakan salah satu teknik (yaitu, penjaga makro versus
#pragma once
).
#pragma once
biasanya tidak.Jawaban:
#pragma once
adalah tidak standar. Ini adalah ekstensi luas (tetapi tidak universal), yang dapat digunakanItu dianggap untuk standardisasi, tetapi ditolak karena tidak dapat diimplementasikan dengan andal. (Masalah terjadi ketika Anda memiliki file yang dapat diakses melalui beberapa mount jarak jauh yang berbeda.)
Ini cukup mudah untuk memastikan bahwa tidak ada konflik penjaga termasuk dalam satu pengembangan. Untuk pustaka, yang dapat digunakan oleh banyak perkembangan yang berbeda, solusi yang jelas adalah menghasilkan banyak karakter acak untuk penjaga menyertakan saat Anda membuatnya. (Editor yang baik dapat diatur untuk melakukan ini untuk Anda setiap kali Anda membuka header baru.) Tetapi bahkan tanpa ini, saya belum pernah mengalami masalah dengan konflik antara perpustakaan.
sumber
pragma once
tidak dapat dengan mudah mengimplementasikan sesuatu yang secara inheren tidak portabel (dan bahkan tidak boleh dianggap) adalah omong kosong lain dari C ++ terbalik dunia.#include
harus dihapus, karena orang dapat secara membabi buta menyalahgunakan arahan.#pragma once
tidak membatasi portabilitas dengan cara apa pun, asalkan Anda tidak akan mengeksploitasi tautan simbolik untuk memecah kompilasi.Bagian §16.6 dari Standar ( konsep N3936 ) menjelaskan
#pragma
arahan sebagai:Pada dasarnya
#pragma once
adalah contoh implementasi khusus dari#pragma
arahan, dan tidak, itu bukan standar. Namun.Hal ini sering didukung secara luas oleh sebagian besar "kompiler utama" termasuk GCC dan Dentang dan oleh karena itu kadang-kadang direkomendasikan untuk menghindari boilerplate termasuk-penjaga.
sumber
#pragma
dan#define
header-guard.#define
header-guard, dia TIDAK punya alasan untuk menulis#pragma once
juga.#pragma once
d, dan jika itu#include
lagi d dapat melewati#include
(bahkan tidak membuka file). gcc melakukan hal yang sama dengan penjaga tajuk, tetapi sangat, sangat rapuh. Yang#pragma
mudah dilakukan, yang sundulannya susah.