Порядок оценки параметра перед функцией, звонящей в C [дубликат]

Они дополняют друг друга.

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

Нет устарели, устаревшие инструкции почти невозможно сделать по соображениям совместимости. Однако некоторые дополнительные расширения могут отсутствовать или удаляться из более новых моделей (например, FMA4 AMD), если они не очень широко распространены. Некоторые из них носят рудиментарный характер, но все, что можно сделать с помощью FPU и MMX, например, можно сделать более эффективно с помощью SSE +.

Они не являются взаимоисключающими в том смысле, что вы можете использовать тот или иной, ведь они являются инструкциями, а не режимами работы (например, реальный vs защищенный режим). Единственный возможный «конфликт» - между MMX и FPU, поскольку они разделяют нижнюю часть одного и того же набора регистров, но имеют другую модель программирования. Новые векторные регистры выросли с 128 до 256 бит и до 512 бит, каждый раз, когда предыдущие регистры стали нижней частью новых.

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

Они похожи на кирпичи Lego, вас ограничивает только ваше воображение (или воображение дизайнеров).


Вот простой список этих расширений набора инструкций. Отображаются только некоторые функции, для полной ссылки см. Intel Manual Vol1 из раздела 9 - 14.

См. Также https://hjlebbink.github.io/x86doc / для оглавления руководства по тома 2 тома 2 (руководство по набору команд) со списком расширений, в котором добавлены инструкции к этой ручной записи.

  • MMX Ввести восемь 64-битных регистров (MM0-MM7) и инструкции для работы с восемью подписанными / неподписанными байтами, четырьмя подписанными / неподписанными словами, двумя подписанными / unsigned dwords.
  • 3DNow! Добавить поддержку одинарной точности с плавающей запятой в MMX. Несколько операций поддерживаются, например, сложение, вычитание, умножение.
  • SSE Представляем восемь / шестнадцать 128-битных регистров (XMM0-XMM7 / 15) и инструкцию для работы с четырьмя операндами с одинарной точностью с плавающей запятой. Также добавьте целочисленные операции в регистры MMX. (MMX-целочисленная часть SSE иногда называется MMXEXT и была реализована на нескольких процессорах, отличных от Intel, без xmm-регистров и части с плавающей запятой SSE.)
  • SSE2 Представляет инструкцию для работы с 2-мя двойными прецизионные операнды с плавающей запятой и с упакованными целыми числами byte / word / dword / qword в 128-битных xmm-регистрах.
  • SSE3 Добавьте несколько разнообразных инструкций (в основном с плавающей запятой), включая специальный тип неравномерной нагрузки ( lddqu), что было лучше на Pentium 4, команде синхронизации, горизонтальной добавке / югу.
  • SSSE3 Опять различный набор инструкций, в основном целых. Первая тасовка, которая берет свой управляющий операнд из регистра вместо жестко запрограммированного (pshufb).
  • SSE4 (SSE4.1, SSE4.2) Добавьте много инструкций: Заполнение вложениями, добавлением / распаковкой, mul + добавлением байтов и некоторыми специализированными функциями add / mul. много пробелов, предоставляя минимальные и максимальные и другие операции для всех целочисленных типов данных (особенно 32-битное целое число отсутствовало), где ранее целочисленный минимум был доступен только для неподписанных байтов и 16-битной подписки. Также масштабирование, округление FP, смешивание, операция линейной алгебры, обработка текста, сравнение. Также не временная нагрузка для чтения видеопамяти или копирование ее обратно в основную память. (Ранее были доступны только магазины NT.)
  • AESNI Добавить поддержку для ускорения симметричного шифрования / дешифрования AES.
  • AVX Добавить восемь / шестнадцать 256-битных регистров (YMM0-YMM7 / 15). Поддержка всех предыдущих типов данных с плавающей точкой. Три команды операнда.
  • FMA Добавить Fused Multiply Добавить и скоррелированные инструкции.
  • AVX2 Добавить поддержку целых типов данных.
  • AVX512F Добавить восемь / тридцать два 512-битных регистра (ZMM0-ZMM7 / 31) и восемь 64-битных регистра маски (k0-k7). Продвигайте большинство предыдущих инструкций до 512 бит в ширину. Необязательные части команды AVX512 add для экспонент и amp; (AVX512ER), разборку / сборку предварительной выборки (AVX512PF), обнаружение конфликтов рассеяния (AVX512CD), сжатие, расширение.
  • IMCI (Intel Xeon Phi) Ранняя разработка AVX512 для первого поколения Intel Xeon Phi ( Knight's Corner).

67
задан corto 17 December 2008 в 22:27
поделиться

4 ответа

Нет, параметры функции не оценены в определенном порядке в C.

Видят ответы Martin York на , Каково все общее неопределенное поведение, о котором должен знать программист C++? .

63
ответ дан Community 7 November 2019 в 10:45
поделиться

Порядок оценки аргументов функции является неуказанным от C99 В§6.5.2.2p10:

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

Подобная формулировка существует в C89.

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

$ gcc -Wall -W -ansi -pedantic test.c -o test
test.c: In function ‘main’:
test.c:9: warning: operation on ‘pa’ may be undefined
test.c:9: warning: operation on ‘pa’ may be undefined
test.c:13: warning: operation on ‘pa’ may be undefined
test.c:13: warning: operation on ‘pa’ may be undefined
test.c:17: warning: operation on ‘pa’ may be undefined
test.c:17: warning: operation on ‘pa’ may be undefined
test.c:20: warning: control reaches end of non-void function
19
ответ дан Robert Gamble 7 November 2019 в 10:45
поделиться

Как другие уже сказали, порядок, в котором оценены аргументы функции, является неуказанным, и нет никакой точки последовательности между оценкой их. Поскольку Вы изменяетесь pa впоследствии при передаче каждого аргумента, Вы изменяетесь и читаете pa дважды промежуточные две точки последовательности. Это - на самом деле неопределенное поведение. Я нашел очень хорошее объяснение в руководстве GCC, которое я думаю, могло бы быть полезным:

стандарты C и C++ определяют порядок, в котором выражения в программе C/C++ оценены с точки зрения точек последовательности, которые представляют частичное упорядочивание между выполнением частей программы: выполняемые перед точкой последовательности и выполняемыми после него. Они происходят после оценки полного выражения (то, которое не является частью большего выражения), после оценки первого операнда & & ||?: или, (запятая) оператор, прежде чем функция вызвана (но после оценки ее аргументов и выражения, обозначающего вызванную функцию), и в определенных других местах. Кроме, как выражено правилами точки последовательности, не определяется порядок оценки подвыражений выражения. Все эти правила описывают только частичный порядок, а не общий порядок, с тех пор, например, если две функции вызваны в рамках одного выражения без точки последовательности между ними, порядок, в котором вызваны функции, не определяется. Однако комитет по стандартам постановил, что вызовы функции не накладываются.

Это не определяется, когда между модификациями точек последовательности к значениям объектов вступают в силу. Программы, поведение которых зависит от этого, имеют неопределенное поведение; C и стандарты C++ определяют, что “Between предыдущая и следующая точка последовательности объект должна изменить его хранимую сумму самое большее однажды оценка выражения. Кроме того, предшествующее значение должно быть только для чтения для определения значения, которое будет сохранено. ”. Если программа нарушает эти правила, результаты на какой-то конкретной реализации совершенно непредсказуемы.

Примеры кода с неопределенным поведением = ++; [n] = b [n ++] и [я ++] = я;. некоторые более сложные случаи не диагностированы этой опцией, и она может дать случайный ложный положительный результат, но в целом это было найдено довольно эффективным при обнаружении этого вида проблемы в программах.

стандарт сформулирован смутно, поэтому существуют некоторые дебаты по точному значению правил точки последовательности в тонких случаях. Ссылки на обсуждения проблемы, включая предложенные формальные определения, могут быть найдены на странице чтений GCC, в http://gcc.gnu.org/readings.html .

5
ответ дан Johannes Schaub - litb 7 November 2019 в 10:45
поделиться

Ответ предоставления корректен, это не определено.

, НО,

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

Это полностью непортативно и ужасная, ужасная вещь сделать, все же.

-1
ответ дан Branan 7 November 2019 в 10:45
поделиться
Другие вопросы по тегам:

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