LINUX.ORG.RU

Отличия C и C++

 ,


1

2

Есть два эквивалентных примера:

#include <stdatomic.h>

int main() {
  int v[2], * p0 = v, * _Atomic p1 = v;
  if (p0 != p1) return 1;
  if (++p0 != ++p1) return 2;
  if (++p0 != (atomic_fetch_add_explicit(&p1, 1, memory_order_relaxed), p1)) return 3;
}

#include <atomic>
using namespace std;

int main() {
  int v[2], * p0 = v; atomic<int*> p1 = v;
  if (p0 != p1) return 1;
  if (++p0 != ++p1) return 2;
  if (++p0 != (p1.fetch_add(1, memory_order_relaxed), p1)) return 3;
}

C-версия делает return 3. Из-за того, что atomic_fetch_add_explicit(&p1, 1, memory_order_relaxed) компилируется в lock addq $0x1,-0x10(%rsp). В C++ lock addq $0x4,-0x10(%rsp) - как и должно быть, учитывает тип. Это баг какой-то или так специально сделано? Зачем?

Ответ на: комментарий от monk

f - функция от одного аргумента произвольного типа
g - функция от одного аргумента типа, совпадающего с типом возвращаемым f

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

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

ты снова явно путаешь использование и инстанциацию — как раз таки будут явно выведены типы компилятором. Неявно, если он сможет снова же вывести их из подставленных аргументов при инстанциации шаблона, либо путем явного указания программистом...

«Типовые шаблонные аргументы» не являются типами — типы будут подставлены при инстанциации — тоесть нет никаких «неизвестных» компилятору типов.

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

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

На нормальных языках (Haskell, Agda, Typed Racket) вполне тип.

Haskell:
ghci> compose f g x = f (g x)
ghci> :t compose
compose :: (t1 -> t2) -> (t3 -> t1) -> t3 -> t2

Typed Racket:
> compose
- : (All (a b c) (-> (-> b c) (-> a b) (-> a c)))

На Си++ описать не получится.

ну и про произвольный тип ты снова в просак попал — поскольку не бывает произвольных типов — для компилятора это будет явно обозначенный тип… Статическая типизация она такая, да.

И какой же обозначенный тип у аргумента f?

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

И какой же обозначенный тип у аргумента f?

какой конкретно будет известно только после инстанциирования шаблона — но можно обозначить, как decltype(g(x)).

safocl ★★
()