Должно ли поведение, определяемое реализацией, быть согласованным между запусками в C ++? - PullRequest
7 голосов
/ 21 июля 2010

Позволяет ли стандартная реализация C ++ реализовать какое-либо поведение, которое, как говорят, определяется реализацией в стандарте таким образом, чтобы оно отличалось между различными запусками одной и той же откомпилированной программы с одними и теми же входными данными?

Например, разрешено ли реализации говорить "это поведение по выходным и что иначе" и реализовывать поведение в соответствии с таким утверждением?

Ответы [ 6 ]

6 голосов
/ 21 июля 2010

Конечно, если реализация документирует, когда именно поведение меняется при разных запусках, это нормально. Обратите внимание, что поведение, определяемое реализацией, является частью параметров абстрактной машины:

Семантические описания в этом международном стандарте определяют параметризованный недетерминированный реферат машина.

Некоторые аспекты и операции абстрактной машины описаны в этом международном стандарте как определяемые реализацией (например, sizeof (int)). Они составляют параметры абстрактной машины. Каждая реализация должна включать документацию, описывающую ее характеристики и поведение в этих отношениях. Такая документация должна определять экземпляр абстрактной машины, которая соответствует этой реализации (далее - «соответствующий экземпляр»).

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

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

3 голосов
/ 21 июля 2010

Один пример, который я могу вспомнить, - это если в программе используются большие или маленькие порядковые номера для чисел.Я считаю, что это определенно считается поведением, определяемым реализацией.

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

Точно так же я предполагаю, что вы могли бы написать компилятор, который бы генерировал как 32, так и 64-битные скомпилированные из одной и той же программы -режим, который он выполнял, мог быть определен во время выполнения.Опять же, в документации должно быть сказано, что целые числа были 32-битными или 64-битными в зависимости от того, как вы их запустили.

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

1 голос
/ 21 июля 2010

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

Можно ожидать, что в большинстве случаев разработчик предоставит некоторые основные гарантии поведения реализации и программы, которую он генерирует для данного набора параметров компилятора / компоновщика. Даже если нагрузка на систему может повлиять на то, насколько оптимизатор может работать с вашей программой, некоторым оптимизаторам будет выделено какое-то ограниченное время, что не должно изменить ожидаемое поведение.

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

1 голос
/ 21 июля 2010

IIRC, system () требуется для существования, но с учетом поведения, определенного реализацией. Нечто подобное system ("ls | grep foo"), естественно, будет иметь разные эффекты в зависимости от того, может ли ваша система выполнить что-то под названием ls, что может варьироваться между запусками. И даже на довольно обычной UNIX-машине, где ls и grep делают то, что вы ожидаете, и их не убирают, результат все равно будет зависеть от наличия файла с именем foo, который, безусловно, будет изменяться время и место выполнения программы и т. д. Это зависит только от того, где вы проведете линию «одних и тех же входных данных». Если машина находится в абсолютно идентичном состоянии, вы можете ожидать идентичного поведения, но никакие два прогона не приведут к тому, что машина действительно будет педантично идентичной. (Даже температура процессора в других совершенно идентичных машинах может привести к некоторому дросселированию, что изменит победителя в некоторых условиях гонки, что явно приведет к другому поведению вашей программы.)

1 голос
/ 21 июля 2010

Определенное реализацией поведение означает

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

Это обязательно для авторов компилятора для документирования поведения конкретной программной конструкции для конкретной реализации.

..... таким образом, что она различается между различными запусками одной и той же скомпилированной программы содни и те же входные данные?

Nopes!

Например, разрешена ли реализация, чтобы сказать «поведение это по выходным и что иначе» и реализовать поведение согласнотакое утверждение?

Я не уверен, но я думаю, что ответ нет .

0 голосов
/ 21 июля 2010

rand(3) в <stdlib.h> можно вызывать из C ++, не зная, какая часть библиотеки C включена в «стандартный C ++», но наверняка есть некоторый механизм, соответствующий стандартам для генерации случайных чисел.1004 *time(3) in <time.h> возвращает текущее время;та же история с C ++ и заходом в библиотеку C.

...