Яке призначення одного знака фунта / хеша (#) на його власному рядку у препроцесорі C / C ++?


145

Я переглядав вихідний код бібліотек Boost , і помітив, що часто є поодинокі знаки фунта без доданих до них директив препроцесора. Я прочитав посібник із посібника та специфікацій GCC-препроцесора, і нічого не можу знайти.

(1) #ifndef BOOST_CONFIG_HPP
(2) #  include <boost/config.hpp>
(3) #endif
(4) #
(5) #if defined(BOOST_HAS_PRAGMA_ONCE)
(6) #  pragma once
(7) #endif

На рядку 4 після знака фунта нічого немає. Який ефект це має? Чи визначено це в специфікації C препроцесора (CPP)?

Оскільки Boost - це бібліотека, що працює на платформі, я вважаю, що будь-яка CPP повинна правильно її розбирати. Який ефект / побічні ефекти матиме у випадку випадкових знаків фунта / хешу у всьому коді?


6
@Zaibis Напр. ім'я виконавчого файлу препроцесора в пакеті GCC - "cpp" (тоді як компілятори - gcc та g ++)
deviantfan

3
CPP означає C-Plus-Plus.
djeidot

6
Не зовсім. Дивіться перше речення en.wikipedia.org/wiki/C_preprocessor
P45 Неминучий

7
@djeidot "cpp" неоднозначний. Ось чому люди використовують "c ++" або "cxx" (x виглядає як + повернувся на 45 градусів), коли вони посилаються на C-Plus-Plus.
Майк Оунсворт

12
@djeidot Ні, CPP - це C-PreProcessor. Це існувало до того, як C ++ навіть існувало.
Леандрос

Відповіді:


185

Само #по собі на лінії взагалі не впливає. Я припускаю, що він використовується для естетичної цінності.

Стандарт C говорить:

6.10.7 Нульова директива

Семантика

Директива щодо попередньої обробки форми

# new-line

не має ефекту.

Стандарт C ++ говорить те саме:

16.7 Нульова директива [cpp.null]

Директива щодо попередньої обробки форми

# new-line

не має ефекту.


4
Це не пояснює мету його використання, хоча і не дає обґрунтування його існування.
StellarVortex

8
"Який ефект має це? Чи визначено це в специфікації C препроцесора (CPP)? ... Яким буде ефект / побічні ефекти, якщо у коді є випадкові знаки фунта / хеша?" Ось що я відповів. Це не має ефекту, але я не хотів міркувати про причину автора його використання. Я це зробив зараз.
Джонатан Уейклі

Вам дали правильні відповіді, що препроцесору це нічого не означає; Я думаю, що це може допомогти якійсь іншій програмі (наприклад, IDE або LINT) зберегти блок директив разом як логічну одиницю. Деякі IDE дозволяють програмістам розширювати або згортати текстові блоки, щоб вони могли відслідковувати логічну структуру файлу.
Спенсер

107

Це робить вихідний код красивим, ось і все.

Виділяє той факт, що весь блок є секцією препроцесора.

І дійсно, і C, і C ++ препроцесори повинні ігнорувати #лінію.


16
А також полегшує навігацію в деяких текстових редакторах (наприклад, {або }vim).
wchargin

@WChargin, це залежить від того, як ти на це дивишся. Якщо ви хочете перейти між двома блоками препроцесора, додавання #не дозволить вам використовувати {або }. Насправді може бути простіше }двічі натиснути, щоб перейти через блок (на прикладі ОП), ніж не вдатися перейти на середину двох блоків.
Шахбаз

3
@Shahbaz Безумовно! Моє правило - "зберігати логічні одиниці разом", так що "абзац" насправді означає "ідею". Я би дотримувався цього правила і при оголошенні препроцесора. Звичайно, це значною мірою питання особистого стилю.
wchargin

46

Завжди перевіряйте авторитетне джерело, а не покладайтеся на інші ресурси. C стандартизовано як ISO 9899 :: 2011, C ++ також має стандарт ISO. Обидва прийняті, а остаточні чернетки доступні шляхом короткого пошуку. Стандарт C зазначається в 6.10.7 (C ++ має приблизно однаковий текст):

Директива щодо попередньої обробки форми

# new-line

не має ефекту.

Це нульова директива , оскільки ;без попереднього виразу в основній мові є нульовим твердженням .

Для препроцесора потрібно лише форматувати / читати, щоб підкреслити, що рядки належать семантично разом. (крапка з комою OTOH є семантично актуальною).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.