Неопределенное, неопределенное и определяемое реализацией поведение

Существует два вида плавания reflection.

  1. Проверка путем повторения элементов типа, перечисления его методов и т. д. Это невозможно с C ++.
  2. Проверка, проверяя, имеет ли тип класса (класс, структура, объединение) метод или вложенный тип, получен из другого определенного типа. Это возможно с помощью C ++ с помощью template-tricks. Используйте boost::type_traits для многих вещей (например, проверка целостности типа). Для проверки существования функции-члена используйте Возможно ли написать шаблон для проверки существования функции? . Для проверки наличия определенного вложенного типа используйте plain SFINAE .

Если вы скорее ищете способы достижения 1), например, посмотрите, сколько методов имеет класс, или как получить строковое представление идентификатора класса, тогда я боюсь, что есть нет стандартного способа C ++ для этого. Вы должны использовать либо

  • Meta Compiler, как Qt Meta Object Compiler, который переводит ваш код, добавляя дополнительную метаинформацию.
  • A Framework, состоящий из макросов, которые позволяют добавлять требуемая метаинформация. Вам нужно будет указать инфраструктуре все методы, имена классов, базовые классы и все, что им нужно.

C ++ создается с учетом скорости. Если вам нужна проверка высокого уровня, например, C # или Java, то, боюсь, я должен сказать вам, что нет никакого способа без каких-либо усилий.

496
задан Taryn 22 March 2017 в 16:18
поделиться

3 ответа

Ну, это, по сути, прямая копия из стандарта

3.4.1 1 поведение, определяемое реализацией неопределенное поведение, где каждая реализация документирует, как выбор сделан

2 ПРИМЕР Примером определенного реализацией поведения является распространение старшего бита, когда знаковое целое число сдвигается вправо.

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

2 ПРИМЕЧАНИЕ Возможное неопределенное поведение варьируется от игнорирования ситуации полностью с непредсказуемыми результатами, до поведения во время перевода или выполнения программы в документированном образом, характерным для среды (с или без выдачей диагностического сообщения), к прекращение перевода или выполнения (с выдачей диагностического сообщения).

3 ПРИМЕР Примером неопределенного поведения является поведение при целочисленном переполнении.

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

2 ПРИМЕР Примером неопределенного поведения является порядок, в котором аргументы функции оцениваются.

93
ответ дан 22 November 2019 в 22:35
поделиться

Undefined Behavior vs. Unspecified Behavior имеет краткое описание этого.

Их заключительное резюме:

Подводя итог, можно сказать, что неопределенное поведение - это обычно то, о чем не стоит беспокоиться, если только от вашего программного обеспечения не требуется переносимость. И наоборот, неопределенное поведение всегда нежелательно и никогда не должно возникать.

10
ответ дан 22 November 2019 в 22:35
поделиться

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

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

неопределенное поведение
Вы делаете что-то не так. Например, у вас есть очень большое значение в int , которое не помещается в char . Как вы поместите это значение в char ? на самом деле нет возможности! Все может случиться, но наиболее разумным было бы взять первый байт этого int и поместить его в char . Просто неправильно делать это для присвоения первого байта, но это то, что происходит под капотом.

неопределенное поведение
Какая из этих двух функций выполняется первой?

void fun(int n, int m);

int fun1()
{
  cout << "fun1";
  return 1;
}
int fun2()
{
  cout << "fun2";
  return 2;
}
...
fun(fun1(), fun2()); // which one is executed first?

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


@eSKay Я думаю, что ваш вопрос стоит отредактировать ответ, чтобы уточнить больше:)

for fun (fun1 (), fun2 ()); - это не поведение "реализация определена"? В конце концов, компилятор должен выбрать один или другой курс?

Разница между определенным реализацией и неопределенным в том, что компилятор должен выбрать поведение в первом случае, но не обязательно во втором случае. Например, реализация должна иметь одно и только одно определение sizeof (int) .Таким образом, нельзя сказать, что sizeof (int) равно 4 для одной части программы и 8 для других. В отличие от неопределенного поведения, когда компилятор может сказать «ОК», я буду оценивать эти аргументы слева направо, а аргументы следующей функции оцениваются справа налево. Это может происходить в одной программе, поэтому называется неопределенным . Фактически, C ++ можно было бы упростить, если бы были указаны некоторые из неопределенных вариантов поведения. Взгляните на Dr. Ответ Страуструпа на этот вопрос :

Утверждается, что разница между тем, что может быть произведено, предоставляя компилятору эту свободу, и , требующим «обычного слева направо». правильная оценка "может иметь значение. Я не убежден, но с бесчисленными компиляторами "там", пользующимися свободой, и некоторыми людьми , страстно защищающими эту свободу, {{1 }} изменения будут трудными и могут потребоваться десятилетия, чтобы проникнуть в далекие уголки миров C и C ++ . Я разочарован тем, что не все компиляторы предупреждают о таком коде, как ++ i + i ++. Точно так же не указан порядок оценки аргументов .

ИМО, слишком много "вещей" оставлено неопределенным, неопределенным, определенным реализацией и т. Д. Однако это легко сказать и даже дать {{1 }} примеры, но их трудно исправить. Следует также отметить, что не так уж и сложно избежать большинства проблем и создать переносимый код.

56
ответ дан 22 November 2019 в 22:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: