Baru mengenal C ++! Jadi saya membaca ini: http://www.learncpp.com/cpp-tutorial/110-a-first-look-at-the-preprocessor/
Pelindung kepala
Karena file header dapat menyertakan file header lainnya, dimungkinkan untuk berakhir dalam situasi di mana file header dimasukkan beberapa kali.
Jadi kami membuat arahan preprosesor untuk menghindari ini. Tapi saya tidak yakin - mengapa kompilator tidak bisa ... tidak mengimpor hal yang sama dua kali?
Mengingat bahwa pelindung tajuk adalah opsional (tetapi tampaknya praktik yang baik), hampir membuat saya berpikir bahwa ada skenario ketika Anda ingin mengimpor sesuatu dua kali. Meskipun saya tidak bisa memikirkan skenario seperti itu sama sekali. Ada ide?
#pragma once
yang memberitahu kompiler untuk hanya memasukkan file itu sekali.Jawaban:
Mereka bisa, seperti yang ditunjukkan oleh bahasa baru yang melakukannya.
Tetapi keputusan desain dibuat bertahun-tahun yang lalu (ketika kompiler C adalah beberapa tahap independen) dan sekarang untuk menjaga kompatibilitas pra-prosesor harus bertindak dengan cara tertentu untuk memastikan kompilasi kode lama seperti yang diharapkan.
Sebagai C ++ mewarisi cara memproses file header dari C itu mempertahankan teknik yang sama. Kami mendukung keputusan desain lama. Tetapi mengubah cara kerjanya terlalu berisiko, banyak kode yang berpotensi rusak. Jadi sekarang kita harus mengajari pengguna baru bahasa bagaimana cara menggunakan termasuk penjaga.
Ada beberapa trik dengan file header yang sengaja Anda sertakan beberapa kali (ini sebenarnya menyediakan fitur yang bermanfaat). Meskipun jika kita mendesain ulang paradigma dari awal kita bisa menjadikan ini cara non-default untuk memasukkan file.
sumber
Sebaliknya tidak akan seekspresif, mengingat bahwa mereka memilih untuk mempertahankan kompatibilitas dengan C dan dengan demikian melanjutkan dengan preprosesor daripada sistem pengemasan tradisional.
Satu hal yang terlintas dalam pikiran saya adalah saya memiliki proyek yang merupakan API. Saya punya dua file header
x86lib.h
danx86lib_internal.h
. Karena internal sangat besar, saya memisahkan bit "publik" ke x86lib.h sehingga pengguna tidak perlu menyisihkan waktu ekstra untuk kompilasi.Ini memperkenalkan masalah lucu dengan dependensi jadi saya akhirnya memiliki aliran yang berjalan seperti ini di x86lib_internal
Saya tidak akan mengatakan itu adalah cara terbaik untuk melakukannya, tetapi itu mencapai apa yang saya inginkan.
sumber
Salah satu kesulitan dengan pengecualian duplikat-header otomatis adalah bahwa standar C relatif diam pada subjek apa yang termasuk nama file. Sebagai contoh, misalkan file utama yang dikompilasi berisi arahan
#include "f1.h"
dan#include "f2.h"
, dan file yang ditemukan untuk arahan keduanya mengandung#include "f3.h"
. Jikaf1.h
danf2.h
berada di direktori yang berbeda, tetapi ditemukan dengan mencari path termasuk, maka akan menjadi tidak jelas#include
arahan dalam file tersebut dimaksudkan untuk memuatf3.h
file yang sama , atau yang berbeda.Hal-hal menjadi lebih buruk jika seseorang menambahkan kemungkinan menyertakan file termasuk jalur relatif. Dalam beberapa kasus di mana file header menggunakan jalur relatif untuk arahan termasuk bersarang, dan di mana orang ingin menghindari membuat perubahan pada file header yang disediakan, mungkin perlu memiliki file header yang digandakan di beberapa tempat dalam struktur direktori proyek. Meskipun ada beberapa salinan fisik dari file header itu, mereka harus dianggap semantik seolah-olah mereka adalah file tunggal.
Jika
#pragma once
direktif memungkinkan pengidentifikasi untuk mengikutionce
, dengan semantik bahwa kompiler harus melewatkan file jika pengidentifikasi cocok dengan satu dari#pragma once
direktif yang ditemui sebelumnya , maka semantik akan jelas; sebuah kompiler yang dapat memberi tahu bahwa suatu#include
arahan akan memuat#pragma once
file bertanda sama dengan yang sebelumnya, itu dapat menghemat sedikit waktu dengan melewatkan file tanpa membukanya lagi, tetapi deteksi tersebut tidak secara semantik penting karena file akan dilewati apakah atau tidak nama file dikenali sebagai kecocokan. Saya tidak mengetahui adanya kompiler yang bekerja seperti itu. Memiliki kompiler mengamati apakah file cocok dengan pola#ifndef someIdentifier / #define someIdentifier / #endif [for that ifndef] / nothing following
dan memperlakukan hal seperti itu setara dengan#pragma once someIdentifier
jika di atassomeIdentifier
tetap didefinisikan, pada dasarnya sama baiknya.sumber