Является ли isupper () макросом или функцией? - PullRequest
4 голосов
/ 05 апреля 2020

Я читал книгу на c ++ ( Полное руководство по программированию на C ++ Уллы Кирх-Принц и Питера Принца; ISBN: 0-7637-1817-3 ), и там упоминалось, что isupper () вместе с islower (), isalpha (), isdi git (), isalnum (), isspace () и isprint () являются макросами для классификации символов .

I найти этот вид странным по двум причинам:

  1. В той же книге говорится о том, что, хотя у макросов могут быть аргументы, они по сути являются просто именами-заполнителями, которые заполняются Определение. Это кажется странным, так как я не знаю, какой текст замены будет работать условно. Это звучит больше в соответствии с функцией или встроенной операцией (например, sizeof).

  2. Это также кажется странным, потому что я слышал, что некоторые люди вызывают эти функции, в то время как Я также слышал, что некоторые люди называют их макросами.

Любое объяснение будет с благодарностью оценено. Я умеренно новичок в этом, поэтому я все еще пытаюсь понять все это. Спасибо.

Ответы [ 2 ]

5 голосов
/ 06 апреля 2020

Стандарт C (насколько я знаю, во всех его версиях) позволяет любой стандартной функции библиотеки также быть определена как макрос. В текущем стандарте C, который скрыт в §7.1.4 (Использование библиотечных функций), абзац 1:

Любая функция, объявленная в заголовке, может быть дополнительно реализована как функционально-подобный макрос определено в заголовке… Любой вызов библиотечной функции, которая реализована в виде макроса, должен расширяться до кода, который оценивает каждый из своих аргументов ровно один раз, при необходимости он полностью защищен скобками, поэтому обычно безопасно использовать произвольные выражения в качестве аргументов.

Макросы могут быть определены стандартной реализацией библиотеки для обеспечения эффективности (хотя это менее важно, чем раньше, теперь, когда большинство компиляторов будут встроенными функциями), но функции также должны быть определенным как функции с точно такой же семантикой, что означает, что вы можете использовать функцию без включения заголовка (при условии, что вы предоставили правильный прототип функции) и что вы можете взять адрес функции.

И, как указано, я Во втором предложении, которое я цитировал, вам не нужно беспокоиться о возможных побочных эффектах макросов, таких как множественная оценка их аргументов - , если в описании функции не указано иное. (Одной из таких функций является getc, которая семантически идентична fgetc, за исключением того, что getc разрешено реализовывать как макрос, который оценивает свой аргумент более одного раза.)

Это никогда не было так что эти функции были реализованы только как макросы (по крайней мере, не в стандартных библиотеках). Но было время, когда было так часто реализовывать простые функции, как макросы, что некоторые люди просто рассчитывали на существующие макросы. Или говорили о них, как будто это было единственное осуществление.

Ничего из этого не имеет место в C ++. C ++ требует, чтобы функции были функциями (а макросы - макросами), а функции находятся в пространствах имен. Это не делало C ++ несовместимым с C; это было просто необходимо для заголовков C ++, которые объявляют функции, совместно используемые с C (то есть теми, чьи имена начинаются с c), до #undef всех (потенциальных) определений макросов после включения соответствующего заголовка C.

5 голосов
/ 06 апреля 2020

Помимо истории, обсуждаемой в комментариях,

isupper официально является функцией в C ++.

См. Документацию в эта ссылка. Он показывает подпись, пространство имен и другие детали.

Редактировать: (ответ на комментарий)

Исторически, да это возможно, это был макрос во время эволюции от C. Потому что это было определено реализацией.

Если вам интересно, как этот макрос мог быть определен, см. this .

...