Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
for(;1;)Мы остановились, добившись успешной компиляции следующего:
for(;P("\n"),R-;P("|"))for(e=C;e-;P("_"+(*u++/8)%2))P("| "+(*u/4)%2);
Вот на С++ вы можете написать subj. На паскале вы не можете такого написать, это одно из преимуществ паскаля перед С++...
When any scalar value is converted to _Bool, the result is 0 if the value compares equal to 0; otherwise, the result is 1
while ("Infinity") {
// ...
}
forever {
// ...
}
#define FOREVER for(;;)Занекропощу: Wiring — это просто C++ (и именно C++, а не C) обмазанный макросами. И таки макроса loop там нет. Есть функция loop(), которая вызывается из замаскированного main:
// cat /usr/share/arduino/hardware/arduino/cores/arduino/main.cpp
#include <Arduino.h>
int main(void)
{
init();
#if defined(USBCON)
USBDevice.attach();
#endif
setup();
for (;;) {
loop();
if (serialEventRun) serialEventRun();
}
return 0;
}loop, которая декрементирует регистр cx, сравнивает с нулём, и если не ноль, по переходит на заданный адрес. Правда она уже давно почти не используется, потому как не даёт выигрыша по сравнению с командами по отдельности, но менее гибкая.jnz и т.д.). Благодаря им, когда-то давно было выгодно писать циклы по убыванию, что позволяло избывиться от отдельной команды сравнения.#include <stdio.h>
int main (int argc, char* argv[])
{
x:
printf("1\n");
goto x;
}
00000000004004f4 <main>:
4004f4: 48 83 ec 08 sub $0x8,%rsp
4004f8: bf fc 05 40 00 mov $0x4005fc,%edi
4004fd: e8 ee fe ff ff callq 4003f0 <puts@plt>
400502: eb f4 jmp 4004f8 <main+0x4>
int main ()
{
loop:
{
printf("1\n");
}
goto loop;
}
400434: 0f 1f 40 00 nopl 0x0(%rax)
что “for (;;)” — 8 символов написать быстрее, чем “while (true)” — 12 символов.
while(true), аргументы:for(;;) выглядит как что-то недописанноеfor(;;) (по ответам на StackOverflow):for(;;)while(1))for(;;) сильнее бросается в глазаtrue — это магическая константа. И говорят, почему тогда не while(42) например? И на основании этого делают вывод, что надо пользоваться forwhile(true), в С while(TRUE), а если использовать while(1), то это не сработает в Java (там условие должно иметь булев тип)в С while(TRUE)
while(1)
#include <stdbool.h>
<...>
while(true)
while((_Bool)1)
(zyx-desktop:zyx:~/tmp/c) 2 % grep -P '^#\s*define\s+TRUE' /usr/include/*.h --files-with-match
/usr/include/atasmart.h
/usr/include/bfd.h
/usr/include/curses.h
/usr/include/gif_lib.h
/usr/include/jmorecfg.h
/usr/include/lcms2.h
/usr/include/lcms.h
/usr/include/ncurses.h
/usr/include/notmuch.h
/usr/include/odbcinstext.h
/usr/include/pth.h
/usr/include/slcurses.h
/usr/include/twolame.h
Как видите, определён в куче файлов, но ни в одном из стандартных заголовков:(zyx-desktop:zyx:~/tmp/c) 2 % grep -P '^#\s*define\s+TRUE' /usr/include/*.h --files-with-match | xargs qfile | cut -d ' ' -f 1 | sort | uniq
dev-db/unixODBC
dev-libs/libatasmart
dev-libs/pth
media-libs/giflib
media-libs/lcms
media-libs/libjpeg-turbo
media-sound/twolame
net-mail/notmuch
sys-libs/ncurses
sys-libs/slang
#define в заголовочном файле — весьма частое явление, считающееся де‐факто стандартом. В приведённом коде замена true на TRUE заработать не должна.считающееся де‐факто стандартом
В приведённом коде замена true на TRUE заработать не должна.
смело говорите что “for (;;)” — 8 символов написать быстрее, чем “while (true)” — 12 символов
while (true), а не for (;;).while(true) {
do_something();
}400438/4096 = 97,763183594
int max(int a, int b) {
return a < b ? b : a;
}
int odd_max(int a, int b) {
int _a;
int _b;
int a_lt_b;
int rec;
int res;
double i;
_a = a;
_b = b;
a_lt_b = 2;
i = 0.0;
while (a_lt_b == 2) {
if (i > 0.0 && odd_max(a, _b) != odd_max(b, _a))
return _a + _b;
if (_a < b)
a_lt_b = 1;
else if (_b < a || _a == b)
a_lt_b = 0;
else {
rec = odd_max(a, _b);
if (rec == _a)
a_lt_b = 0;
else if (rec == b)
a_lt_b = 1;
else
a_lt_b = 2;
}
i = i + 0.1;
}
if (a_lt_b)
res = _b;
else
res = _a;
return res;
}
$ cc -O2 max.c
$ objdump -d a.out
a.out: file format elf64-x86-64
<...>
0000000000400570 <max>:
400570: 39 fe cmp %edi,%esi
400572: 89 f8 mov %edi,%eax
400574: 0f 4d c6 cmovge %esi,%eax
400577: c3 retq
<...>
0000000000400580 <odd_max>:
400580: 39 f7 cmp %esi,%edi
400582: 89 f0 mov %esi,%eax
400584: 0f 4d c7 cmovge %edi,%eax
400587: c3 retq
<...>
long long fib(int n) {
if (n < 3)
return 1;
return fib(n - 1) + fib(n - 2);
}
for(;;)vswhile(true) совсем как-то несерьёзно.совсем как-то несерьёзно.
long long fib_00(int n) {
if (n < 3)
return 1;
return fib_00(n - 1) + fib_00(n - 2);
}
long long fib_01(int n) {
if (n < 3)
return 1;
long long prev1 = fib_01(n - 1);
long long prev2 = fib_01(n - 2);
return prev1 + prev2;
}
long long fib_02(int n) {
if (n < 3)
return 1;
long long prev1 = 1;
if (n - 1 > 2)
prev1 = fib_02(n - 2) + fib_02(n - 3);
long long prev2 = 1;
if (n - 2 > 2)
prev2 = fib_02(n - 3) + fib_02(n - 4);
return prev1 + prev2;
}
long long fib_03(int n) {
if (n < 3)
return 1;
long long prev1 = 1;
long long prev2 = 1;
if (n > 3) {
prev1 = fib_03(n - 2) + fib_03(n - 3);
if (n > 4)
prev2 = fib_03(n - 3) + fib_03(n - 4);
}
return prev1 + prev2;
}
long long fib_04(int n) {
if (n < 3)
return 1;
long long prev1 = 1;
long long prev2 = 1;
if (n > 3) {
long long prev3 = fib_04(n - 3);
prev1 = fib_04(n - 2) + prev3;
if (n > 4)
prev2 = prev3 + fib_04(n - 4);
}
return prev1 + prev2;
}
Дело в том, что есть довольно много людей считающих что «компилятор тупой».
Я пытаюсь натолкнуть людей на то, что иногда нужно заглянуть внутрь и внутри совсем не страшно.
Что быстрее while (true) или for (;;)?Быстрее? В смысле, какой из двух бесконечных циклов быстрее завершится?
400438/4096 = 97,763183594Вы забыли перед делением перевести адреса из шестнадцатиричной системы счисления в десятичную, должна получиться 1024-я страница.
400520/4096 = 97,783203125
Пронесло. Страница памяти одна. Да это 97 страница Виртуальной памяти Виртуального адресного пространства процесса.
while (true) и for (;;) идентичны по производительности между собой и с любыми оптимизациями -Ox.Про сравнение производительности бесконечных циклов мне еще слышать не приходилось. Так, надо было лучше бенчмарк провести, чтобы уж наверняка…
смело говорите что “for (;;)” — 8 символов написать быстрее, чем “while (true)” — 12 символов.Ах, ну, если сравнивать так, тогда вы забыли про различные автодополнения редакторов кода, которые значительно ускоряют ввод. Да и
while (true) выглядит более выразительно, читаемо и понятно даже школьнику. И потом, при желании, while (true) всегда можно сократить до while (1).
Что быстрее while (true) или for (;;)?