Оптимизация строгого псевдонима Clang против недостижимого кода, нарушающего строго псевдоним

Вы можете использовать дату календаря dateComponents из Date to Date и передать только компонент дня:

let date = Date(timeIntervalSinceReferenceDate: 0)     //  "2001-01-01 00:00:00 +0000" 
let days = Calendar.current.dateComponents([.day], from: date, to: Date()).day    // 5971
1
задан Павел 20 March 2019 в 23:34
поделиться

2 ответа

Спасибо всем за ваши комментарии! Вы помогли мне понять проблему намного лучше.

Просто чтобы уточнить, почему я делаю это и чего я действительно хотел: я портирую Clang на какую-то конкретную платформу. Таким образом, моя цель здесь состояла в том, чтобы понять, содержит ли этот тест (из нашей системы тестирования автогенов) ошибку, или, скорее, это ошибка компиляции clang. По результатам этого обсуждения я отправил ошибку llvm ( https://bugs.llvm.org/show_bug.cgi?id=41178 ).

Еще раз спасибо!

0
ответ дан Павел 20 March 2019 в 23:34
поделиться

Оператор выражения

                    *(long long *)grp = 0;

имеет неопределенное поведение из-за доступа к объекту типа int[4] через lvalue другого несовместимого типа (long long) - - нарушение строгого алиасинга, как вы видите в вопросе. Но это не должно быть ограничено поведением во время выполнения . (Потенциальная) проблема, видимая во время трансляции, поведение во время трансляции также не определено, и поэтому таков результат каждого выполнения.

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

Что касается обновления

Ваш пример (4) имеет совершенно четкое поведение. Основными соображениями здесь являются

  • Явно разрешено преобразовывать значение одного типа указателя объекта в другой тип указателя объекта. Существуют предостережения по поводу выравнивания результата, но C требует, чтобы он всегда работал для преобразования в char *, и требует обратного преобразования, чтобы воспроизвести исходное значение указателя (которое не имеет проблемы с выравниванием, если оно действительно с самого начала). [+1121]

  • Разрешается доступ к представлению любого объекта через lvalue символьного типа. Другими словами, char * разрешено создавать псевдоним любой части любого объекта, поэтому даже если вы не не обращаетесь к чему-либо напрямую через значения char *, переданные в assign(), соответствующий компилятор должен Предположим, что эти указатели могут иметь псевдоним любого объекта в программе.

  • Нулевой указатель любого типа может быть преобразован в другой тип указателя объекта, что приводит к нулевому указателю целевого типа.

  • Используя аргумент type для функции assign() способом, согласующимся с реализацией этой функции, программа гарантирует, что к каждому задействованному объекту в конечном итоге получают доступ (только) через lvalue его правильного типа. [ тысячу сто двадцать четыре]

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

0
ответ дан John Bollinger 20 March 2019 в 23:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: