2017-02-16 2 views
1

У меня есть класс C++ вроде этого:Может ли компилятор оптимизировать вызов метода?

class MyClass { 
    int calculate(int arg1) const; 
    void side_effect(int arg) const; 
} 

, который используется, как это:

{ 
    MyClass m; 
    m.calculate(100); 
    m.side_effect(100); 
} 

Является ли компилятор свободный пропустить m.calculate() вызов - так как я не держу на возвращаемое значение? Для метода side_effect() я действительно надеюсь, что компилятор не сможет пропустить вызов - хотя метод отмечен const?

EDIT: Причина, я задаю этот вопрос в том, что моя calculate() функции имеет побочный эффект, но за счет использования mutable помечаются как const. Теперь в нормальном случае я хочу удержать возвращаемое значение, и вся проблема спорная, но в случае, проиллюстрированном выше, меня интересует только то, что побочный эффект был вызван (Да, я знаю, что это не Симпатичная ...). Читая ответы/комментарии, я получаю ощущение, что, по вашему мнению, компилятор может определить, имеет ли метод побочные эффекты; что было удивительно для меня?

+2

Результат должен быть как-если бы вызывалась функция. Если это не влияет, как вы можете сказать разницу? –

ответ

5

Это зависит от того, что m.calculate() делает.

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

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

const не имеет никакого отношения к этому. Итак, если m.side_effect() имеет побочные эффекты, его нельзя пропустить.

0

Компиляция оптимизирует любой код, который не влияет на время выполнения, если он может сказать, что во время компиляции, например. ветви, которые никогда не называются, и значения, которые никогда не используются. Здесь могут быть удобны данные и объекты Const, поскольку их значение известно во время компиляции. Помещение const на сам метод не изменит этого: это просто означает, что вы знаете, что этот метод не изменит его объект. Сам объект по-прежнему не является константой, поэтому, хотя метод является const, компилятор не знает, что значения данных могут быть в момент выполнения этого метода. По-прежнему существует вероятность того, что неконстантный метод изменил объект в какой-то момент.

Кроме того, методы, объявленные в таком классе, являются встроенными: они будут заменены самим кодом, а не вызовом функции. Какое бы «действие» метод side_effect не было непосредственно записано в код вместо самого вызова функции. Все это не будет оптимизировано, если оно фактически ничего не делает, что не должно быть проблемой.

BTW. Метод const может по-прежнему влиять на связанные объекты, например. доступ к данным через указатель внутри класса, он может свободно изменять данные, на которые указывает, но не может изменить адрес самого указателя.

+1

"они будут заменены самим кодом, а не вызовом функции". Они ** могут быть заменены кодом. Никакой компилятор, о котором я не слышал, наверняка встроит методы 'inline'. Он будет решать, что лучше во время компиляции. – riodoro1

0

Давайте различать 'can и' should ', чтобы быть более поставленными. Что касается «can», способность компилятора оптимизировать некоторые конструкции кода cetain зависит от дизайна кода и того, насколько «умный» компилятор. Как больше намеков у компилятора, так как более тесно он может что-то оптимизировать.

В вашем случае, если функции side_effect и calculate являются фиктивными и ничего не делать (и calculate возвращает статический жёстками значения), они могут быть оптимизированными.Кроме того, их параметры также могут быть оптимизированы (пожалуйста, не смешивайте этот случай с «должен») в том месте, где они объявлены и определены. Но по этой причине (особенно если используется какой-то простой компилятор), вам, вероятно, нужно дать больше подсказок о параметрах, объявляющих их как ссылки на const, чтобы передавать их по значению.

В этом случае ваш код

MyClass m; 
m.calculate(100); 
m.side_effect(100); 

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

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

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