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) - как и должно быть, учитывает тип. Это баг какой-то или так специально сделано? Зачем?

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

«auto у аргов функции раскрывается в шаблонные типы». То есть выведен не будет. Останется неизвестным до использования compose.

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

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

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

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

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

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

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

Так это и значит, что «their parameter lists and, for non-static member functions, cv/ref(since C++11)-qualifications» являются частью полного имени, определяющего функцию.

не имени, но сигнатуры...

safocl ★★
()
Ответ на: комментарий от 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 ★★
()
Ответ на: комментарий от monk

имя входит в сигнатуру)
по сему явно не перевода, но вполне возможно терминологии — тут она состыковывает общение многил людей.

safocl ★★
()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.