Насколько расширяемость стандартной библиотеки C влияет на программы на C ++?

Возьми этот код:

int issuecode(int i)
{
return 2 * i;
}

int main(int argc, char **argv)
{
return issuecode(argc);
}

Насколько я понимаю, если скомпилировать как программу на C, она будет иметь неопределенное поведение. Я основываюсь на этих стандартных цитатах:

С99, 7,26 (или С11, 7.31)

Следующие имена сгруппированы под отдельными заголовками для удобства. Все внешние имена, описанные ниже, зарезервированы независимо от того, какие заголовки включены в программу.

С99, 7.26.2 (или С11, 7.31.2)

Имена функций, которые начинаются с is или же toи строчные буквы могут быть добавлены к объявлениям в <ctype.h> заголовок.

С99, 7.1.3 (или C11, 7.1.3)

  1. Каждый заголовок объявляет или определяет все идентификаторы, перечисленные в связанном с ним подпункте, и, необязательно, объявляет или определяет идентификаторы, перечисленные в соответствующем подпункте будущих направлений библиотеки, и идентификаторы, которые всегда зарезервированы либо для любого использования, либо для использования в качестве идентификаторов области файла.

    […]
    • Все идентификаторы с внешней связью в любом из следующих подпунктов (включая будущие направления библиотеки) всегда зарезервированы для использования в качестве идентификаторов с внешней связью.
  2. […] Если программа объявляет или определяет идентификатор в контексте, в котором она зарезервирована (кроме как разрешено в 7.1.4), или определяет зарезервированный идентификатор как имя макроса, поведение не определено.

Исходя из вышеизложенного, я считаю, что имя функции issuecode фактически зарезервировано для использования в <ctype.h>и поэтому программа технически имеет UB.

Вопрос 0 (проверка работоспособности): Является ли мое чтение стандарта правильным, а поведение программы технически не определено?

Вопрос 1: Будет ли программа иметь UB, если она скомпилирована как код C ++?

Я полагаю, что ответ «нет», так как из следующих цитат я бы сказал, что «будущие направления библиотеки» C не являются частью стандартной библиотеки C ++, но я не совсем уверен.

С ++ 11, 21,7

  1. Таблицы 74, 75, 76, 77, 78 и 79 описывают заголовки <cctype>, <cwctype>, <cstring>, <cwchar>, <cstdlib> (преобразования символов) и <cuchar>соответственно.

  2. Содержимое этих заголовков должно быть таким же, как заголовки стандартной библиотеки C <ctype.h>, <wctype.h>, <string.h>, <wchar.h>, а также <stdlib.h> и заголовок C Unicode TR, соответственно, со следующими модификациями:

Ни в одной из «следующих модификаций» не упоминаются дополнительные зарезервированные идентификаторы. Таблица 74 представляет собой так называемый список имен функций, таких как isdigit а также isalnum,

С ++ 11, С.2

1. В этом подпункте обобщено содержимое стандартной библиотеки C ++, включенной в стандартную библиотеку C. Он также суммирует явные изменения в определениях, объявлениях или поведении из библиотеки Standard C, отмеченные в других подпунктах (17.6.1.2, 18.2, 21.7).

7. Стандартная библиотека C ++ предоставляет 209 стандартных функций из библиотеки C, как показано в таблице 153.

Опять же, таблица 153 представляет собой налоговый список.

Вопрос 2: Если предположить, что я ошибаюсь в вопросе 1, и в программе действительно есть UB на C ++, повлияют ли на это следующие изменения?

namespace foo {

int issuecode(int i)
{
return 2 * i;
}

}

using namespace foo;

int main(int argc, char **argv)
{
return issuecode(argc);
}

Замечания: Стандартные цитаты взяты из черновиков N1256 (C99), N1570 (C11) и N3242 (C ++ 11), которые являются последними общедоступными черновиками для соответствующих языковых версий.

14

Решение

Следующие имена сгруппированы под отдельными заголовками для удобства. Все внешние имена, описанные ниже, зарезервированы независимо от того, какие заголовки включены в программу.

Существует предопределенный список функций, которые зарезервированы, если ваша функция не конфликтует с именами, в этом нет проблем.

Имена функций, начинающиеся с is или to, и строчные буквы могут быть добавлены в объявления в <ctype.h> заголовок.

Оперативный термин есть может быть добавленным к <ctype.h> заголовок. Бит «is or to» — это просто руководство по организации объявлений.

Так что на самом деле там никогда не было неопределенного поведения …

Что касается C ++, я думаю, что это следует той же идее, например:

namespace foo{
int isupper ( int c );
}

#include <cctype>
using namespace foo;
int main(void){
isupper(92);
}

Это должно приводить к ошибке компилятора, потому что ваша функция сталкивается с именем с функцией C, но из-за пространства имен это легко исправить, добавив std:: или foo:: к началу разговора.

1

Другие решения

C ++ 11 17.6.1.2 Заголовки

172) Заголовки стандартной библиотеки C (Приложение D.5) также определяют имена в глобальном пространстве имен, тогда как заголовки C ++ для C
библиотечные средства (17.6.1.2) может также определить имена в глобальном пространстве имен.

В стандартной библиотеке C ++, однако, объявления (за исключением
имена, которые определены как макросы в C), находятся в пределах области имен (3.3.6) пространства имен std. это
неопределенные
будут ли эти имена сначала объявлены в глобальной области имен, а затем введены
в пространство имен std с помощью явных объявлений using (7.3.3).

Так что, если вы не включите <cctype> поведение четко определено. Если вы делаете, это не указано.

0

По вопросам рекламы [email protected]