Что происходит, если Вы не возвращаете значение в C++?

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

L4 = []

for e in L1:
  i2 = L2.index(e) # looks for the index (i2) of the element e of L1 in L2
  L4.append(L3[i2]) # append lo L4 the element at index i2 in L3

print(L4)
#=> ['birne', 'apfel', 'kirsche', 'banane']

, которая может быть записана как один слой:

[ L3[L2.index(e)] for e in L1 ]
14
задан Jason Baker 16 November 2008 в 04:40
поделиться

6 ответов

другой SomeStruct становился созданным и инициализированным где-нибудь неявно?

Думают о том, как структура возвращается. Если и x и y 32 бита, это является слишком большим для помещений в регистр на 32-разрядной архитектуре, и то же относится к 64-разрядным значениям на 64-разрядной архитектуре (@Denton упоминания ответа Дворянства, как более простые значения возвращены), таким образом, это должно быть выделено где-нибудь. Было бы расточительно использовать "кучу" для этого, таким образом, это должно быть выделено на стеке. Но это не может быть на стековом фрейме Вашего getSomeStruct функция, так как это не допустимо больше после функциональных возвратов.

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

существует также оптимизация как "именованная оптимизация возврата значения", где дополнительные копии могут игнорироваться. Так, имел Вас, использовал пропавших без вести return, результат будет создан непосредственно на месте, выделенном вызывающей стороной, вместо того, чтобы создать временный файл и скопировать его.

Для знания больше о том, что происходит необходимо посмотреть на функцию вызывающей стороны. Это инициализирует (для обнуления) "пустое" SomeStruct, которому Вы позже присваиваете возвращаемое значение Вашего getSomeStruct функция? Или это делает что-то еще?

7
ответ дан 1 December 2019 в 06:54
поделиться

Уменьшение с конца функции, которая, как объявляют, возвращает значение (явно не возвращая значение) приводит к неопределенным последствиям. Для gcc необходимо запустить с -Wall переключатель командной строки, который включает большинство полезных предупреждений. Определенное предупреждение gcc, которое управляет предупреждением Вас, хочет, -Wreturn-type (который включен в -Wall, я просто упоминаю это для полноты).

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

20
ответ дан 1 December 2019 в 06:54
поделиться

Соглашения о вызовах для большинства современных архитектур ЦП указывают конкретный регистр для пасования назад функционального возвращаемого значения вызывающей стороне. Вызывающая сторона делает вызов функции и затем использует указанный регистр в качестве возвращаемого значения. Если Вы явно не возвратите значение, то вызывающая сторона будет, тем не менее, использовать любой мусор, оказывается, находится в том регистре.

компилятор будет также использовать все регистры, которые он имеет в наличии для внутреннего вычисления в функции. Регистр, определяемый для содержания возвращаемого значения, будет также использоваться для misc вычисления в функции. Таким образом, когда Вы забываете указывать возвращаемое значение, весьма обычно найти, что правильное значение было удивительно возвращено вызывающей стороне: компилятор использовал тот регистр, чтобы хранить Ваш объект.

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

8
ответ дан 1 December 2019 в 06:54
поделиться

Я нахожу это интересным. С используемыми опциями по умолчанию следующие компиляторы имеют следующее поведение при компиляции эти GetSomeStruct() функция:

  • Microsoft VC, все версии (начиная с VC6 так или иначе):

    error C4716: 'getSomeStruct' : must return a value

  • Цифровой Марс:

    Warning 18: implied return of getSomeStruct at closing '}' does not return value

  • Comeau:

    warning: missing return statement at end of non-void function "getSomeStruct"

  • gcc:

    никакая ошибка или предупреждение

, Учитывая следующие несколько предложений из стандарта (6.6.3 Абзацев 2):

оператор возврата А без выражения может использоваться только в функциях, которые не возвращают значение, то есть, функцию с типом возврата пусто, конструктор (12.1), или деструктор (12.4).... Течение от конца функции эквивалентно возврату без значения; это приводит к неопределенному поведению в возвращающей значение функции.

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

3
ответ дан 1 December 2019 в 06:54
поделиться

Для меня компилятор не позволил его: http://codepad.org/KkzVCesh

2
ответ дан 1 December 2019 в 06:54
поделиться

Вы не получили предупреждения, потому что Вы не имели -Wall -Werror включенный. (Как указано в других ответах)

Однако я думаю, что Вы, вероятно, получили заполненную нулями структуру как результат, потому что объект стека был значением по умолчанию, созданным в функции вызывающей стороны, возможно с явными нулевыми аргументами, или иначе из-за нулей на стеке?

1
ответ дан 1 December 2019 в 06:54
поделиться
Другие вопросы по тегам:

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