2012-03-04 2 views
2

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

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

В принципе, я пытаюсь сказать, что переменная, которая передается, является изменчивой. Надеюсь, я поняла. Но, если я сделаю проход по ссылке, которая изменит весь сценарий ... я прав?

volatile int a; 
int main() 
{ 
    function(a); 
    return 1; 
} 
int function b(int a) 
{ 

    int x=a; 

    int y=a; 

    return x*y; 

} 

ответ

7

volatile классификатор сообщает компилятору, что переменная может изменить не то, что он изменится. В любом случае он не может спонтанно измениться; что-то должно заставить его измениться - даже если эта причина является внешней по отношению к коду.

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

Если код был изменен (и сделал в силе и компилируется) таким образом:

volatile int a; 

int function(void) 
{ 
    int x=a; 
    int y=a; 

    return x*y; 
} 

int main() 
{ 
    function(); 
    return 1; 
} 

Тогда эффект volatile здесь просто, что компилятор будет явно назначить x и y без применения каких-либо оптимизаций, которые иначе были бы возможны ,Без классификатора, компилятор может в противном случае (когда оптимизации включены) уменьшить function() до всего:

int function(void) 
{ 
    return a * a ; 
} 

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

int main() 
{ 
    return 1; 
} 

Если a летуч, то присвоения x и yсусла произойти, если function() является называется.

Цель volatile является указание компилятору, что переменная может измениться за пределами кода, который сгенерировал компилятор (не то, что он будет изменить). Он обычно используется для обеспечения правильного поведения, когда переменная ссылается либо на аппаратный регистр, либо на память, которая совместно используется потоками, процессами или даже процессорами или ядрами в процессоре. Он также может использоваться для предотвращения «оптимизации» кода, который требуется (например, пустые счетчики ожидания «занято-ожидание»). В вашем примере (или, вернее, его пересмотре) a не ссылается ни на одну подобную сущность, поэтому код будет вести себя так, как ожидалось, но, возможно, будет менее эффективным, чем в противном случае.

+0

Но если я сделаю что-то вроде этого ... – Invictus

+0

int square (volatile int * ptr) { int a, b; a = * ptr; b = * ptr; return a * b; } – Invictus

+0

и позвоните в Square (& a) .... Теперь это даст мне разные значения ... Надеюсь, я прав .... Я? – Invictus

5

Там нет никакой связи между глобальной области видимости volatile int a и функции-сферы int a параметра. Они полностью независимы, и любая ссылка на a внутри функции относится к параметру int a. volatile int a никогда не используется вообще в этой программе.

Если вы должны были пройти volatile int a в качестве аргумента в функции, то она не будет иметь никакого значения, потому что значение этого a бы прочитать один раз и скопировать в a параметра функции, которая сама по себе не volatile.

+0

Итак, вы имеете в виду, если у меня есть функция b (volatile int a) в качестве параметра ... это будет иметь значение ..... ?? – Invictus

+1

Это было бы очень необычно. Что вы пытаетесь достичь? –

+0

Я пытаюсь сказать, объявляю ли я функцию b (volatile int a) .... тогда значение копируется, но если значение является volatile, оно сообщает компилятору скопировать местоположение своей памяти ... это мое замешательство. – Invictus

5

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

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

Смежные вопросы