Я просто хочу знать, что делает функция ниже
static int myfunc(int val)
{
return *(volatile int *)val;
}
Я просто хочу знать, что делает функция ниже
static int myfunc(int val)
{
return *(volatile int *)val;
}
Если val является указателем, когда вы передаете его этой функции, он гарантирует, что значение, указанное этим указателем, будет считано и возвращено вызывающему.
Я подозреваю, что это может быть хитростью для встроенных устройств, где иногда операция чтения значения по адресу оказывает некоторое влияние на аппаратное обеспечение.
Например, чтение из аппаратного FIFO выведет значение чтения из FIFO.
Маркировка здесь указатель как volatile заставит компилятор не оптимизировать чтение, если он обнаруживает, что значение не используется.
Пример:
#define FIFO_ADDRESS 0x800050
static int myfunc(int val)
{
return *(volatile int *)val; // the address *will* be read
}
static int bad( int val )
{
return *(int*)val; // might be optimized to nop()
// by the compiler if the value
// is not used by the caller
}
int main(){
bad( FIFO_ADDRESS ); // could be NOP since return value is not used
myfunc( FIFO_ADDRESS ); // *WILL* perform a READ operation on the FIFO,
// even though the result is not used, because
// of the volatile keyword
}
Обратите внимание, что я сделал бы это по-другому, возможно, с помощью яркого имени макроса:
#define FORCE_INT_PTR_READ( address ) *(volatile int *)address
Не могли бы вы привести пример использования в вашем случае?
Кажется, он пытается запутать оптимизатора (и, возможно, пользователя). Он принимает целое число, рассматривая его как указатель на целое число и разыгрывая его. "Volatile" гарантирует, что оптимизатор будет генерировать код для этого разыменования в этой точке и не позволит оптимизатору опустить выборку из памяти. Обычно это используется для доступа к зарегистрированным аппаратным регистрам памяти,
Он выполняет следующие действия:
val
должно совпадать с физическим аппаратным адресом. При чтении с таких адресов ключевое слово volatile необходимо, так как содержимое регистра аппаратного обеспечения может измениться в любое время.static
означает, что функция имеет локальную область действия.Обратите внимание, что если целевая ОС использует виртуальную адресацию (например, ПК), ОС просто даст вам пощечину на пальцах, если вы попытаетесь запустить этот код.
В целом, это плохо написанный код, который не является ни безопасным, ни четким, ни портативным. Вы не получите никаких ценных знаний, глядя на него.
Он передает val
указателю и возвращает его значение. Звонки на myfunc()
будут работать, только если ваш вид int i, j;
i = 10;
j = myfunc( (int)&i )`
Это должно установить j на 10
НО он не будет работать на 64-битных системах, где sizeof(int *)
равно 8 и, следовательно, больше, чем sizeof(int)
или на некоторых старых системах с sizeof(int) == 2