LINUX.ORG.RU

Предрасчёт константных значений. С

 


0

1
uint32_t f(uint32_t c)
{
    return sin(c) * c + 33454 - 444;
}

#define REF f(667)
#define REF_4 f(755)

При подстановке этих дефайнов компиллятор просчитает их значения или бросит, чтобы они просчитались в рантайме?

★★★★

Последнее исправление: SL_RU (всего исправлений: 1)

Научу тебя ловить рыбу.

$ cat test.c 
#include <stdio.h>
#include <stdint.h>
#include <math.h>

uint32_t f(uint32_t c)
{
    return sin(c) * c + 33454 - 444;
}

#define REF f(667)
#define REF_4 f(755)

int main(){
	printf("%d  %d\n", REF, REF_4);
}
 $ gcc -O2 test.c -lm
 $ objdump -d a.out 
в выводе objdump ищем код функции main:
0000000000400590 <main>:
  400590:	b9 74 83 00 00       	mov    $0x8374,%ecx
  400595:	ba 1c 83 00 00       	mov    $0x831c,%edx
  40059a:	be 64 07 40 00       	mov    $0x400764,%esi
  40059f:	bf 01 00 00 00       	mov    $0x1,%edi
  4005a4:	31 c0                	xor    %eax,%eax
  4005a6:	e9 c5 ff ff ff       	jmpq   400570 <__printf_chk@plt>
  4005ab:	0f 1f 44 00 00       	nopl   0x0(%rax,%rax,1)
Отлично, mov $0x8374,%ecx и mov $0x831c,%edx как раз забивают нужные константы.

Waterlaz ★★★★★
()
Ответ на: комментарий от Waterlaz

Но это не оправдывает отсутствие constexpr в языке :)

Stil ★★★★★
()

Как повезёт, расчитывать на константы не стоит.

mashina ★★★★★
()

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

anonymous
()

компиллятор просчитает их значения или бросит, чтобы они просчитались в рантайме?

да

anonymous
()
Ответ на: комментарий от anonymous

Не так. Нужно так:

компиллятор просчитает их значения или бросит, чтобы они просчитались в рантайме

Да

anonymous
()

А что мешает посчитать на калькуляторе и объявить const int? 21-й век на дворе, а до сих пор дифайны юзаете. :)

xoomer
()
Последнее исправление: xoomer (всего исправлений: 1)

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

no-such-file ★★★★★
()
Ответ на: комментарий от trycatch

вах, спасибки. Отличная вещь!

SL_RU ★★★★
() автор топика
Ответ на: комментарий от anonymous

Зачем нужен constexpr, когда и без него у компилятора достаточно информации, чтобы знать, что можно посчитать в compile-time, а что нет? Чем больше компилятор умеет считать в compile-time, тем он круче.

KivApple ★★★★★
()
Ответ на: комментарий от KivApple

За тем, что constexpr гарантирует расчёт статически.

RazrFalcon ★★★★★
()
Ответ на: комментарий от anonymous

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

Не знаешь язык ассемблера? Ну так я тоже не знаю, но хоть немного надо представление иметь о регистрах и инструкциях mov, call, jmp.

Waterlaz ★★★★★
()
Последнее исправление: Waterlaz (всего исправлений: 1)
Ответ на: комментарий от anonymous

Что - да? :-)

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

anonymous
()
Ответ на: комментарий от anonymous

Не совсем так. Сделай gcc -E. Как и должно быть, получится:

printf("%d  %d\n", f(667), f(755));
Так что формально вызывается. Просто в процессе оптимизации компилятор видит, что это можно посчитать заранее и считает. Если бы f была более сложной функцией, этого, конечно, нельзя было бы сделать.

hotpil ★★★★
()
Ответ на: комментарий от hotpil
0000000000400590 <main>:
  400590:	b9 74 83 00 00       	mov    $0x8374,%ecx
  400595:	ba 1c 83 00 00       	mov    $0x831c,%edx
  40059a:	be 64 07 40 00       	mov    $0x400764,%esi
  40059f:	bf 01 00 00 00       	mov    $0x1,%edi
  4005a4:	31 c0                	xor    %eax,%eax
  4005a6:	e9 c5 ff ff ff       	jmpq   400570 <__printf_chk@plt>
  4005ab:	0f 1f 44 00 00       	nopl   0x0(%rax,%rax,1)

Покажи мне то место, где здесь «формально вызывается» f?

А еще скажи, какое к этому всему имеет отношение вывод препроцессора?

Waterlaz ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.