Гость
Форумы / C++ [игнор отключен] [закрыт для гостей] / выполнить пример с инкрементом не на компиляторе MS ++ / 25 сообщений из 49, страница 1 из 2
02.11.2018, 18:11
    #39727362
tchingiz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
выполнить пример с инкрементом не на компиляторе MS ++
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
#include <iostream>
int f (int &p){
    return p++;
}
void main(){
  int i = 0;
  i= i + f(i);
  std::cout<<i<<"\n";

  i = 0;
  i= f(i) + i;
  std::cout<<i;
}


в с++ от перемены мест слогаемых сумма не меняется -- пример выдает две единицы.

на сишарпе - меняется, такой пример выдает 0 и 1





Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
using System;
using System.IO;

class a {
  private static int f (ref int p){
    return p++;
  }
  public static void Main(){
    int i = 0;
   i= i  + f(ref i);
    Console.WriteLine(i);
    i = 0;

    i=f(ref i) +i;
    Console.WriteLine(i);
  }
}


они (сишарписты) почему-то, считают, что другой компилятор выдаст 0 и 1
...
Рейтинг: 0 / 0
02.11.2018, 18:38
    #39727371
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
выполнить пример с инкрементом не на компиляторе MS ++
Формально p++ возвращает p а затем происходит ++. ИМХО правильно работает в C#.
...
Рейтинг: 0 / 0
02.11.2018, 18:58
    #39727378
clihlt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
выполнить пример с инкрементом не на компиляторе MS ++
Скорее всего связано с тем что в C# стековая арифметика.
В первом случае сначала пушаем на стек 0, вычисляем результат функции (0) и пушаем на стек, суммируем два значения на вершине стека: 0 + 0 = 0

Во втором сначала пушаем на стек результат функции (0), потом занчение i (которое поменялось из-за ++ на 1),уммируем два значения на вершине стека: 0 + 1 = 1.

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

авторони (сишарписты) почему-то, считают, что другой компилятор выдаст 0 и 1

Может и выдаст, а мож и не выдаст. Это ж UB.
...
Рейтинг: 0 / 0
02.11.2018, 19:27
    #39727392
tchingiz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
выполнить пример с инкрементом не на компиляторе MS ++
Dima TФормально p++ возвращает p а затем происходит ++. ИМХО правильно работает в C#.
а в си++ чтоли не правильно?
функция возращает 0, но она должна выполнится до сложения, её приоритет выше.

i= i + f(i); это 1 (f уже применили) + 0
...
Рейтинг: 0 / 0
02.11.2018, 19:29
    #39727394
tchingiz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
выполнить пример с инкрементом не на компиляторе MS ++
clihlt,
сенкс
...
Рейтинг: 0 / 0
02.11.2018, 20:07
    #39727415
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
выполнить пример с инкрементом не на компиляторе MS ++
tchingizфункция возращает 0, но она должна выполнится до сложения, её приоритет выше.
но никто не не запрещает получить значения других аргументов до вызова функции.

Я не большой спец в С++, подожди, пусть спецы скажут почему оно именно так считается. Возможно UB, а может и регламентировано где-то.
...
Рейтинг: 0 / 0
02.11.2018, 20:22
    #39727420
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
выполнить пример с инкрементом не на компиляторе MS ++
Dima TВозможно UB, а может и регламентировано где-то.

UB: https://en.cppreference.com/w/cpp/language/eval_order
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
02.11.2018, 20:49
    #39727425
tchingiz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
выполнить пример с инкрементом не на компиляторе MS ++
tchingizDima TФормально p++ возвращает p а затем происходит ++. ИМХО правильно работает в C#.
а в си++ чтоли не правильно?
функция возращает 0, но она должна выполнится до сложения, её приоритет выше.

i= i + f(i); это 1 (f уже применили) + 0
объяснение аннулируется.

Жук доработал пример

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
#include <iostream>

int f (int &p){
    return p++;
}

int main(){
  int j = 0;
  int i = 0;
  i =  i+  f(i) + f(i)  ;//  +  f(i)  +  f(i)   ;
  std::cout<<i<< " ";
  i=0;
  i =   f(i) + f(i) +i ;//  +  f(i)  +  f(i)   ;
  std::cout<<i<< " ";
}


получается 3 и 2.

я бы ожидал 3 и 3
...
Рейтинг: 0 / 0
02.11.2018, 20:52
    #39727427
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
выполнить пример с инкрементом не на компиляторе MS ++
tchingizполучается 3 и 2.

я бы ожидал 3 и 3
5 и 100500 тоже правильные ответы потому что UB 21722924
...
Рейтинг: 0 / 0
02.11.2018, 20:58
    #39727430
tchingiz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
выполнить пример с инкрементом не на компиляторе MS ++
tchingiz,

пардон 2 и 3 (а не 3 и 2)
...
Рейтинг: 0 / 0
02.11.2018, 21:06
    #39727431
ZyK_BotaN
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
выполнить пример с инкрементом не на компиляторе MS ++
Dima Ttchingizполучается 3 и 2.

я бы ожидал 3 и 3
5 и 100500 тоже правильные ответы потому что UB 21722924
вы слишком широко трактуете UB в плане порядка вічисления функций.
диапазон дозволенных вариантов решений не так велик.
UB - только порядок вычислений, который может дать всего несколько разных вариантов результата.
...
Рейтинг: 0 / 0
02.11.2018, 21:20
    #39727436
tchingiz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
выполнить пример с инкрементом не на компиляторе MS ++
блин, я ассоциативность за порядок вычислений понимал.


Dimitry Sibiryakov,

автор This is not to be confused with left-to-right and right-to-left associativity of operators: the expression f1() + f2() + f3() is parsed as (f1() + f2()) + f3() due to left-to-right associativity of operator+, but the function call to f3 may be evaluated first, last, or between f1() or f2() at run time

то есть, в любом порядке вычислятся f1, f2 и f3,
а, потом, сложение результатов идет слева - направо?
(f1() + f2()) + f3()
...
Рейтинг: 0 / 0
02.11.2018, 21:45
    #39727441
OoCc
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
выполнить пример с инкрементом не на компиляторе MS ++
tchingizблин, я ассоциативность за порядок вычислений понимал.


Dimitry Sibiryakov,

автор This is not to be confused with left-to-right and right-to-left associativity of operators: the expression f1() + f2() + f3() is parsed as (f1() + f2()) + f3() due to left-to-right associativity of operator+, but the function call to f3 may be evaluated first, last, or between f1() or f2() at run time

то есть, в любом порядке вычислятся f1, f2 и f3,
а, потом, сложение результатов идет слева - направо?
(f1() + f2()) + f3()

если переписать выражения используя операторы то всё обьясняется. Исполнение начинается с самой внутренней функции
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
#include <iostream>

int f (int &p){
    return p++;
}

int main(){
  int j = 0;
  int i = 0;

// i= i  + f(ref i);
i.operator=(f(&i).operator+(f(&i).operator+(i))));   
//     5      3       4       1        2              //2
 
// j =   f(j) + f(j) +j;
j.operator=(j.operator+(f(&j).operator+(f(&j))));     
//     5           4      2       3       1           //3
}
...
Рейтинг: 0 / 0
02.11.2018, 22:27
    #39727449
OoCc
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
выполнить пример с инкрементом не на компиляторе MS ++
OoCcесли переписать выражения используя операторы то всё обьясняется. Исполнение начинается с самой внутренней функции
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
#include <iostream>

int f (int &p){
    return p++;
}

int main(){
  int j = 0;
  int i = 0;

// i= i  + f(ref i);
i.operator=(f(&i).operator+(f(&i).operator+(i))));   
//     5      3       4       1        2              //2
 
// j =   f(j) + f(j) +j;
j.operator=(j.operator+(f(&j).operator+(f(&j))));     
//     5           4      2       3       1           //3
}



Хмм.. чушь написал
...
Рейтинг: 0 / 0
03.11.2018, 10:38
    #39727511
tchingiz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
выполнить пример с инкрементом не на компиляторе MS ++
OoCc,
Через указатели на си тоже 2 и 3.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
#include <stdio.h>
int f (int *p){
    return (*p)++;
}
void main(){
  int i = 0;
  i= i + f(&i) + f(&i);
  printf (" %d  \n", i);
 // std::cout<<i<<"\n";

  i = 0;
  i= f(&i) + f(&i) + i;
  printf (" %d  \n", i);
}



лично меня расстраивает, что теперь одним предложением нельзя объяснить,
что такое ассоциативность
В Болски я понимал, что написано - вызвать все функции и складывать слева направо,
а теперь надо неделю разбираться
...
Рейтинг: 0 / 0
03.11.2018, 12:01
    #39727525
Arm79
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
выполнить пример с инкрементом не на компиляторе MS ++
Dima TФормально p++ возвращает p а затем происходит ++. ИМХО правильно работает в C#.
+1

Оператор ++ (справочник по C#)
Оператор инкремента (++) увеличивает операнд на 1. Оператор инкремента может находиться перед своим операндом или после него: ++variable и variable++.

Примечания
Первый случай — это операция префиксного инкремента. Результатом операции является значение операнда после его увеличения.

Второй случай — это операция постфиксного инкремента. Результатом операции является значение операнда до его увеличения .
...
Рейтинг: 0 / 0
03.11.2018, 12:21
    #39727526
ZyK_BotaN
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
выполнить пример с инкрементом не на компиляторе MS ++
tchingizлично меня расстраивает, что теперь одним предложением нельзя объяснить,
Можно. Просто не нужно ассоциативности ждать там, где используются функции с побочным эффектом. Которые по определению и функциями то не являются.
...
Рейтинг: 0 / 0
04.11.2018, 21:33
    #39727917
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
выполнить пример с инкрементом не на компиляторе MS ++
Тут UB же ...
...
Рейтинг: 0 / 0
04.11.2018, 21:49
    #39727926
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
выполнить пример с инкрементом не на компиляторе MS ++
...
Рейтинг: 0 / 0
04.11.2018, 22:00
    #39727931
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
выполнить пример с инкрементом не на компиляторе MS ++
Кэп, тебе не надоело повторять чужие посты двухдневной давности?..
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
05.11.2018, 12:19
    #39728041
tchingiz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
выполнить пример с инкрементом не на компиляторе MS ++
похоже дошло, что такое ассоциативность.
авторthis is not to be confused with left-to-right and right-to-left associativity of operators: the expression f1() + f2() + f3() is parsed as (f1() + f2()) + f3()


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
#include <stdio.h>


int f (int *p){
    return (*p)++;
}


void main(){
  int i = 0;
  int j;
  i= (i + f(&i)) + f(&i);    // ->>>>>> i + f(&i) + f(&i)  это 2
  printf (" %d  \n", i);
 // std::cout<<i<<"\n";

  i = 0;
  i = i +  (f(&i)  + f(&i)); //  ---->>>>   f(&i)  + f(&i) +i   это 3
  printf (" %d  \n", i);
}




i + f(&i) вычисляет 1, к которой прибавляет единица от второго вызова f(&i);


f(&i) + f(&i) вычисляет 1, к которой прибавляется двойка от i после двух вызовов f

и никакого UB

другой компилятор cpp вычислит то же самое.
...
Рейтинг: 0 / 0
05.11.2018, 13:57
    #39728090
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
выполнить пример с инкрементом не на компиляторе MS ++
А теперь прочитай-таки следующую строчку.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
05.11.2018, 14:04
    #39728093
tchingiz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
выполнить пример с инкрементом не на компиляторе MS ++
Dimitry SibiryakovА теперь прочитай-таки следующую строчку.


слушаюсь

авторbut the function call to f3 may be evaluated first, last, or between f1() or f2() at run time.

ты намекаешь, что
Код: plaintext
1.
(i + f(&i)) + f(&i)  



может таки вернуть 2, а не 1?
...
Рейтинг: 0 / 0
05.11.2018, 14:04
    #39728094
полудух
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
выполнить пример с инкрементом не на компиляторе MS ++
Dima TФормально p++ возвращает p а затем происходит ++. ИМХО правильно работает в C#.
не может в MS работать правильно, т.к. она берёт мировые стандарты и переиначивает на свой лад
аля "а давайте сделаем тоже самое, но по-своему"
ну и поскольку это армия индусов MS, то результат немного предсказуем - получаем перекошенный новый стандарт
т.о. она никак не может сделать что-то лучше из того, что уже вылизано и стандартизировано.
...
Рейтинг: 0 / 0
05.11.2018, 14:07
    #39728096
tchingiz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
выполнить пример с инкрементом не на компиляторе MS ++
это попользовать? чтобы увидеть другой результат?
автор/Gd использовать соглашение о вызовах __cdecl
/Gr использовать соглашение о вызовах __fastcall
/Gz использовать соглашение о вызовах __stdcall
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / выполнить пример с инкрементом не на компиляторе MS ++ / 25 сообщений из 49, страница 1 из 2
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]