LINUX.ORG.RU

C++ арифметика указателей: является ли код эквивалентным?

 , ,


1

2

Первый второму?

#include <iostream>
#include <cstddef>
#include <new>

int main()
{
    alignas(float) std::byte stor[3*sizeof(float)];
    
    for (int i = 0; i < 3; ++i)
        new (stor + i*sizeof(float)) float(i);
    
    for (int i = 0; i < 3; ++i)
        std::cout << *std::launder( reinterpret_cast<float*>(stor + i*sizeof(float)) ) << std::endl;
}
#include <iostream>
#include <cstddef>

int main()
{
    alignas(float) std::byte stor[3*sizeof(float)];
    
    for (int i = 0; i < 3; ++i)
        new (stor + i*sizeof(float)) float(i);
    
    for (int i = 0; i < 3; ++i)
        std::cout << ((float*)stor)[i] << std::endl;
}


Последнее исправление: sostupid (всего исправлений: 2)
Ответ на: комментарий от aureliano15

Тебе уже несколько человек подтвердили, что все эти конструкции абсолютно идентичны.

ЕМНИП, в мусульманском праве нужно 4 свидетеля, чтобы подтвердить измену жены.

А по правилам местрого форума, сколько людей должно сказать X, чтобы X стал верным?

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

Если это очевидные вещи, то на поиски вряд ли должно уходить много времени. Ну, я так примерно чувствую.

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

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

Этот уважаемый человек — тоже неосилятор. Потому что в том же стандарте c89 и про это говорится:

3.2.2.1 Lvalues and function designators

An lvalue is an expression (with an object type or an incomplete type other than void) that designates an object. /24/ When an object is said to have a particular type, the type is specified by the lvalue used to designate the object. A modifiable lvalue is an lvalue that does not have array type, does not have an incomplete type, does not have a const-qualified type, and if it is a structure or union, does not have any member (including, recursively, any member of all contained structures or unions) with a const-qualified type.

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

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

Если это очевидные вещи, то на поиски вряд ли должно уходить много времени. Ну, я так примерно чувствую.

Так ты ищи, а не чувствуй. Если, конечно, не потролить зашёл.

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

Этот уважаемый человек — тоже неосилятор.

Неосилятор тут ты. Русского языка. Перечитай ещё раз и вдумайся:

член комитета по C++

sostupid
() автор топика
Ответ на: комментарий от Dudraug

Ты имеешь права тут ждать ответа, а тебе имеют права не отвечать, а вот требовать уже права у тебя нет.

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

Неосилятор тут ты. Русского языка. Перечитай ещё раз и вдумайся:

член комитета по C++

Перечитай и вдумайся:

A modifiable lvalue is an lvalue that does not have array type

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

Так ты вбросил, или солгал. Тогда ты просто лжец и тролль.

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

Зачем мне читать цитату из стандарта C89? Очевидно, что если член комитета по C++, то цитаты должны быть из соответствующего стандарта.

sostupid
() автор топика
Ответ на: комментарий от aureliano15

Так ты ищи, а не чувствуй.

Я не нашёл. Поэтому прошу помощи.

sostupid
() автор топика

вижу

arr[i] <=> *(arr + i)
обмазанное кастом в с-style.

код первого и второго примера неэквивалентный. хоть результат и одинаков.

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

эх. а зачетку-то я дома оставил.

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

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

Вот весь вопрос в том, одно ли это и то же.

В смысле последовательности арифметики/кастов, порядок операций разный, а вот

результат и одинаков.

так ли это?

sostupid
() автор топика
Ответ на: комментарий от conalex

а что не правильно?

А я сказал, что неправильно? Я наоборот сказал: "Правильно. Всё равно на пересдачу."

я заочник и все такое...

C++ не щадит никого.

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

так ли это?

если под результатом понимать результат работы программы (участка вычурного кода с этими самыми кастами) - то да, так. оно выхлопнет одно и тоже.

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

А я сказал, что неправильно? Я наоборот сказал: «Правильно. Всё равно на пересдачу.»

а, так это вы так шутите, евгений ваганыч? не понял, извиняйте.

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

если под результатом понимать результат работы программы (участка вычурного кода с этими самыми кастами) - то да, так. оно выхлопнет одно и тоже.

Несколько месяцев назад сюда вбрасывали код, был дикий срач. По мотивам.

#include <cstdio>

typedef int (*Function)();

static Function Do;

static int EraseAll() {
    return puts("rm -rf /");
}

void NeverCalled() {
    Do = EraseAll;  
}

int main() {
    NeverCalled();
    return Do();
}
https://wandbox.org/permlink/8fUB30gOCNfG9jsl выводит «rm -rf /».
Убираем кое-что
#include <cstdio>

typedef int (*Function)();

static Function Do;

static int EraseAll() {
    return puts("rm -rf /");
}

void NeverCalled() {
    Do = EraseAll;  
}

int main() {
    return Do();
}
https://wandbox.org/permlink/y2O7cPx1fieeZcvW выводит «rm -rf /».

Отсюда вопрос. Достаточно ли выхлопывать одно и то же, чтобы быть эквивалентным кодом?

sostupid
() автор топика
Ответ на: комментарий от conalex

А вдруг... можно сделать второй ОП-код не эквивалентным первому на каком-нибудь компиляторе с какими-нибудь флагами?

Или если таких компиляторов и флагов подобрать не удалось, то значит ли это, что код эквивалентен или не значит? На этот вопрос вообще возможно ответить?

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

А вдруг... можно сделать второй ОП-код не эквивалентным первому на каком-нибудь компиляторе с какими-нибудь флагами?

что значит «вдруг»?

Или если таких компиляторов и флагов подобрать не удалось, то значит ли это, что код эквивалентен или не значит? На этот вопрос вообще возможно ответить?

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

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

Ты это, если хочешь поговорить про нюансы стандарта - пиши про них прямо. С подходом «все дураки, а я тут нарыл нестыковку, но вам не покажу» мало что получится.

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

Зачем мне читать цитату из стандарта C89? Очевидно, что если член комитета по C++, то цитаты должны быть из соответствующего стандарта.

В последнем стандарте си++17 тоже есть:

11.3.4 Arrays

[skip]

5 [ Note: Conversions affecting expressions of array type are described in 7.2. Objects of array types cannot be modified, see 6.10. — end note ]

член комитета по C++

Так что продолжаю утверждать, что член комитета по си++ — неосилятор.

Я не нашёл. Поэтому прошу помощи.

Может быть поищу, тогда отпишусь. Но не обещаю. Дело в том, что стандарт — это формальный почти юридический документ, а не руководство или учебник. Соответственно, и написано там всё через ж... полуюридическим языком, а не для нормальных людей. Я подозреваю, что одной цитатой тут, скорее всего, не обойтись, т. к. в выражении используются вещи из разных частей стандарта. А именно: с одной стороны массивы, указатели и их приведение, а с другой — скалярные типы и их размеры. И чтобы объяснить это выражение на «языке стандарта», придётся компоновать разные его куски. Для этого и существуют книги, где всё уже скомпоновано нормальным человеческим языком. А иначе они были бы не нужны, и все читали только стандарт.

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

кому нужно это подтверждение ? вам
и почему подтверждать должен кто то на форуме ? не должен
вы ищете ? вы и ищите

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

так ему компилера мало, он хочет какие то доказательства из стандарта
очевидно мальченка троллит

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

Несколько месяцев назад сюда вбрасывали код, был дикий срач.

Помню этот срач, т. к. одним из разжигателей был я, как и инициатором продолжения.

Отсюда вопрос. Достаточно ли выхлопывать одно и то же, чтобы быть эквивалентным кодом?

Ну так там же речь шла об ub и неадекватности поведения компиляторов в случае их появления. А в твоих примерах ub нет, поэтому у тебя — достаточно.

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

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

4.3.4.2 Assigning an Array to Another Array A variable can be assigned to or initialized with another variable but an array cannot be assigned to or initialized with another array. The following statement is not valid and leads to a compilation error: arrayl=array2

пошел нахрен троляка с этого форума, иди мамке сиську смокчи

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

«Компилера» действительно мало, и разговор про стандарт мог бы быть интересен. Если бы не стиль общения автора.

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

4.3.4.2 Assigning an Array to Another Array A variable can be assigned to or initialized with another variable but an array cannot be assigned to or initialized with another array. The following statement is not valid and leads to a compilation error: arrayl=array2

А откуда это? Я ни в си++17, ни в си89, ни в си11 не нашёл.

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

В последнем стандарте си++17 тоже есть:

Ты не то выделил. Главное в твоей цитате — «see 6.10». А там сказано «An lvalue is modifiable unless its type is const-qualified or is a function type.» Видишь что-то про массивы?

Так что продолжаю утверждать, что член комитета по си++ — неосилятор.

Да ты и не такую чушь утверждать можешь, что с тебя взять.

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

see _basic.lval_

Ok, let's see

http://eel.is/c++draft/basic.lval#10

An lvalue is modifiable unless its type is const-qualified or is a function type. [ Note: A program that attempts to modify an object through a nonmodifiable lvalue expression or through an rvalue expression is ill-formed ([expr.ass], [expr.post.incr], [expr.pre.incr]). — end note  ]

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

вы тупой или что ?

8.3.4 Arrays [dcl.array] ... 5 [Note: conversions affecting lvalues of array type are described in _conv.array_. Objects of array types cannot be modified, see _basic.lval_. ] ....

_basic.lval_ не означает что там будет разжевано почему она не модифицируемая

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

вы тупой или что ?

Или вы.

[Note: conversions affecting lvalues of array type are described in _conv.array_. Objects of array types cannot be modified, see _basic.lval_. ]

Это примечание, которое ссылается на раздел стандарта для своего обоснования. В данном случае, это устаревшее примечание.

Когда-то под определением UB было написано, что разыменовывать нулевой указатель это UB, хотя это уже было не так. Потом примечание заменили на то, что попытка модифицировать константный объект это UB.

_basic.lval_ не означает что там будет разжевано почему она не модифицируемая

Это пункт, который должен обосновать примечание. Но он не может, т.к. там не сказано, что массивы это немодифицируемые типы.

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

Да ты и не такую чушь утверждать можешь, что с тебя взять.

А ты не можешь привести пруфца. Ты вбросил очень провакционное утверждение, что ЧЛЕН КОМИТЕТА по с++ сказал, что в стандарте нет пруфов того, что все кодеры считают аксиомой. Об этом должно быть много инфы, если ввести в гугл запрос «присваивание массива массиву с++», что на рус., что на анг., то первые 100 ссылок должны быть об этом. Но там тишина. Я попросил пруфца на столько провакационное и сенсационное заявление, а ты пруф предоставить отказался. Ты вбросил и не стал доказывать. Это похоже на ложь и клевету.

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

Зачем тебе пруф на то, что это говорил именно член комитета?

Присваивание требует modifiable lvalue слева, любое lvalue является modifiable, кроме lvalue const-типа и обозначающего функции.

Значит массив может стоять слева от знака присваивания. Ему здесь ничего не мешает.

Впрочем, можешь поискать другие пункты, не дающие присваивать массивы друг другу, я не утверждаю, что их нет.

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

http://www.open-std.org/jtc1/sc22/open/n2356/decl.html

8.3.4 Arrays [dcl.array] ... 5 [Note: conversions affecting lvalues of array type are described in _conv.array_. Objects of array types cannot be modified, see _basic.lval_. ] ....

Ну, это и я приводил. :-) Только в последнем стандарте си++17 этот пункт идёт под номером 11.3.4:

11.3.4 Arrays

[skip]

5 [ Note: Conversions affecting expressions of array type are described in 7.2. Objects of array types cannot be modified, see 6.10. — end note ]

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

Если со мной общаются нормально, то у меня стиль общения нормальный.

А когда говорят «иди читай про преобразования типов!» так, как будто говорящий УЖЕ доказал переход от одной записи выражения к другой, а через полсуток оказывается, что он нихрена не знет, а только

Может быть поищу, тогда отпишусь. Но не обещаю.

— это типичное хамство.

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

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

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

Objects of array types cannot be modified

Ты не то выделил.

Да нет. Я как раз то самое выделил. Перевожу на русский: «объекты типа массива не могут быть модифицированы». А значит, и присваивать им ничего нельзя, кроме как при инициализации.

Главное в твоей цитате — «see 6.10». А там сказано «An lvalue is modifiable unless its type is const-qualified or is a function type.»

Вот именно. Перевожу на русский: «lvalue является модифицируемым, кроме константных и функциональных типов.»

Видишь что-то про массивы?

Вижу что-то про lvalue. А про массивы я процитировал выше.

Так что продолжаю утверждать, что член комитета по си++ — неосилятор.

Да ты и не такую чушь утверждать можешь, что с тебя взять.

Пока что чушь здесь утверждаешь ты.

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

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

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

«объекты типа массива не могут быть модифицированы»

int main()
{
    int a[2];
    a[0] = 0;
}

А я модифицировал объект типа массива. Где теперь твой бог?

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

он хочет понимать стандарт на своем уровне знаний

Совершенно верно. И на моём уровне знаний мне изветсно, что Notes в стандарте не имеют никакой силы. Поэтому ссылаться на Note для обоснования — это смешно.

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

А я модифицировал объект типа массива. Где теперь твой бог?

Ты модифицировал элемент массива, а не объект, который является константным указателем на 0-й элемент.

Notes в стандарте не имеют никакой силы.

Notes в стандарте имеют такую же силу, как и всё остальное. Иначе их бы в стандарте просто не было.

Совершенно верно. И на моём уровне знаний

Ну только если на твоём уровне.

Если со мной общаются нормально, то у меня стиль общения нормальный.

Первая стрелка — ок. (Хотя это и стандарт C, ну да ладно). А дальше?

Это стиль экзаменатора. Ты получил ответ на вопрос и убедился, что в стандарте есть то, о чём ты говорил, что его нет. Дальше мог продолжить поиск самостоятельно, потому что другие люди не менее заняты, чем ты.

Ненамного твоих познаний хватило.

Типа, «садись, два». Я же говорю, тон экзаменатора. Но это форум, а ты — не профессор.

Может быть поищу, тогда отпишусь. Но не обещаю.

— это типичное хамство.

Т. е. то, что я допустил возможность того, что поищу за тебя и, если что, отпишусь, но не обещаю — это хамство?! Да ты из тех, кто на полном серьёзе уверен, что им все должны.

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