2013-04-24 2 views
1

Испытано простой utf8 STRLEN функции и был весьма удивлен тем, что ствол лязг полностью устранить его (НКУ не делает):Предоставляет ли C++ CTFE?

static int strlenutf8(const char* s) 
{ 
    int i = 0, l = 0; 
    while (s[i]) 
    { 
    if ((s[i] & 0xc0) != 0x80) l++; 
    l++; 
    } 
    return j; 
} 

int main() 
{ 
    return strlenutf8("bla"); 
} 

лязг ++ -O3 -S -fverbose-ASM:

main:         # @main 
    .cfi_startproc 
# BB#0:         # %entry 
    movl $3, %eax 
    ret 

Это как функция оценки времени компиляции D. Является ли это даже законным в C++?

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

+0

Оптимизатор может делать все, что захочет, до тех пор, пока он не нарушит указанное поведение. – SLaks

+0

Что такое CTFE? – rubenvb

+1

@rubenvb Я полагаю, что «компиляция функции оценки времени». –

ответ

3

constexpr требуется только для контекстов постоянного выражения (например, для вывода шаблонов), но функция constexpr не может быть оценена во время компиляции.

Золотое правило оптимизации программ на С ++ является as-if правила:

семантических описания в настоящем стандарте определить параметризированную недетерминированную абстрактную машину. В этом Международном стандарте нет требований к структуре соответствующих реализаций. В частности, им не нужно копировать или эмулировать структуру абстрактной машины. Скорее, соответствующие реализации необходимы для подражания (только) наблюдаемого поведения абстрактной машины, как описано ниже.

С очень необходимой сноской:

Это положение иногда называют «как если бы» правила, потому что реализация может свободно игнорировать любые требования настоящего стандарта до тех пор, как результат как если бы это требование выполнялось, насколько это можно определить из наблюдаемого поведения программы. Например, фактическая реализация не должна оценивать часть выражения, если она может вывести, что ее значение не используется и что никаких побочных эффектов, влияющих на наблюдаемое поведение программы, не производится.

с основным НО: копировальные конструкторами с побочными эффектами (например, они увеличивают в «конструктор копирования называется» COUNT переменных или эквивалент) не должен быть включена в «как если бы». Это входит в 12.8/31:

При соблюдении определенных критериев, реализация может пропустить копирование/перемещение строительства объекта класса, даже если копировать/перемещать конструктор и/или деструктор для объекта есть сторона последствия. В таких случаях реализация рассматривает источник и цель пропущенной операции копирования/перемещения как просто два разных способа обращения к одному и тому же объекту, а уничтожение этого объекта происходит в более поздние времена, когда эти два объекта были бы разрушен без оптимизации.123This элизия копировать/перемещать операции, называется копия элизия, допускается в следующих случаях (которые могут быть объединены, чтобы исключить несколько копий): [...]

+0

EBCO - еще один прикладом. –

+0

Акроним везде! Это правда, но эффект этого (не каждый объект имеет другой адрес) на самом деле не связан с этой проблемой IIANM? – rubenvb

2

Согласованный компилятор C++ - это , который требуется для поддержки выражения во время компиляции. Оценка времени компиляции выражений не constexpr составляет , разрешено по правилу as-if; так как ваша функция strlenutf8 не имеет (видимых) побочных эффектов, компилятору разрешено ее преодолевать.

2

Как бы вы написать соответствующую стандарту C++ программа, которая будет определять эту оптимизацию? Если вы не можете придумать способ, оптимизация в порядке (ну, ладно, если там - это не путь). Компилятор не обязан делать что-то неэффективно только потому, что вы можете посмотреть на сгенерированный код.

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