Что такое пользовательские соглашения о вызовах?

Что это такое? И как я затронут ими как разработчик?

Похожие страницы:
Каковы различные соглашения о вызовах в C/C++ и что каждый имеет в виду?

7
задан Community 23 May 2017 в 11:55
поделиться

4 ответа

A соглашение о вызовах описывает, как что-то может вызывать другую функцию. Это требует, чтобы параметры и состояние были переданы другой функции, чтобы она могла правильно выполнить и вернуть управление.Способ, которым это делается, должен быть стандартизирован и определен, чтобы компилятор знал, как упорядочить параметры для использования вызываемой удаленной функцией. Существует несколько стандартных соглашений о вызовах, но наиболее распространенными являются fastcall , stdcall и cdecl .

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

  • нестандартное соглашение о вызовах или соглашение, которое не широко используется (например, если вы строите архитектуру с нуля).

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

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

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

И как они влияют на меня как на разработчика?

С вашей точки зрения как разработчика, вам, вероятно, все равно; это оптимизация, которая произойдет автоматически.

10
ответ дан 6 December 2019 в 21:12
поделиться

Не думаю, что тебе действительно нужно заботиться.

Обычные соглашения о вызовах - это такие вещи, как __stdcall и __fastcall. Они определяют, как ваша подпись вызова преобразуется в макет стека, кто (вызывающий или вызываемый) отвечает за сохранение и восстановление регистров и т. Д. Например, __fastcall должен использовать больше регистров, тогда как __stdcall будет использовать больше стека.

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

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

1
ответ дан 6 December 2019 в 21:12
поделиться

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

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

Это наиболее распространено при взаимодействии между различными языками. Например, C и Pascal имеют разные условные обозначения о том, как передавать параметры. С точки зрения Си, соглашение Паскаля о вызове можно назвать пользовательским соглашением о вызове.

-121--3926280-

Слишком трудно читать, сначала позаботьтесь об исключениях.

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

Это один из нескольких раз, это много отдельных возвращений в методе будет приемлемым

private bool CanExecuteAdd(string parameter) 
{       
    if (this.Script == null)
        return false;

    if (parameter.NotIn([] {"Step", "Element", "Choice", "Jump", "Conditional jump"})
        throw new Exception("Unknown Add parameter {0} in XAML.".F(parameter));

    if (parameter == "Step") 
        return true;

    if (parameter == "Element")
        this.ElementSelectedInLibrary != null && this.SelectedStep != null;

        // etc, etc
}

О, и .NotIn является методом расширения, противоположным этому, я бы представить

public static bool In<T>(this T obj, IEnumerable<T> arr)
{
    return arr.Contains(obj);
}
-121--1293170-

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

Что это такое: большинство компиляторов и такие используют стандартное соглашение о вызове, такое как cdecl, где аргументы функции толкаются в определенном порядке в стек и так далее.

0
ответ дан 6 December 2019 в 21:12
поделиться

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

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

Это наиболее часто встречается при взаимодействии между различными языками. Например, C и Pascal имеют разные соглашения о том, как передавать параметры. С точки зрения языка Си, соглашение о вызове в Паскале может быть названо пользовательским соглашением о вызове.

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

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