Pisałem trochę kodu C ++ i omyłkowo pominąłem nazwę funkcji WSASocket
. Jednak mój kompilator nie zgłosił błędu i skojarzył my SOCKET
z wartością całkowitą 1 zamiast z prawidłowym gniazdem.
Kod, o którym mowa, powinien wyglądać następująco:
this->listener = WSASocket(address->ai_family, address->ai_socktype, address->ai_protocol, NULL, NULL, WSA_FLAG_OVERLAPPED);
Ale zamiast tego wyglądało to tak:
this->listener = (address->ai_family, address->ai_socktype, address->ai_protocol, NULL, NULL, WSA_FLAG_OVERLAPPED);
Pochodzący z innych języków, wygląda na to, że może to być rodzaj anonimowego typu. Jak nazywa się funkcja, w przypadku gdy jest to naprawdę funkcja?
Jaki jest jej cel?
Trudno go znaleźć, kiedy nie wiesz, od czego zacząć.
for
wyrażeniu iteracji pętli *, ala
dla (int i = 0, j = 0; i <10; ++ i, --j) ... `i=0;j=0;x=i++,j=6;
x i j będzie równe 6, a i i tak będzie 1. Jeśli zachowanie i ++ zostanie nadpisane, pozostanie 0. Ale każda instrukcja jest wywoływana i po osiągnięciu tego,
samego rozszerzenia są odrzucane i wywoływany jest następny pseudosekwencyjny punkt. Tak więc pierwszy=
przypisuje tylko część po ostatnim,,
ale każdy punkt jest wywoływany. W każdym razie: nie rozumiem, dlaczego kompilator nie ostrzega przed przedefiniowaniem deklaracji funkcji i zamiast tego zmienia kod na coś ogcc
ig++
z-Wall
opcją powiedz:warning: left-hand operand of comma expression has no effect [-Wunused-value]
Odpowiedzi:
Operator przecinka † oblicza lewą stronę, odrzuca jej wartość iw rezultacie zwraca prawą stronę.
WSA_FLAG_OVERLAPPED
wynosi 1, i to jest wynik wyrażenia; wszystkie inne wartości są odrzucane. Żadne gniazdo nie jest nigdy tworzone.† Chyba że jest przeciążony. Tak, może być przeciążony. Nie, nie powinieneś go przeciążać. Odsuń się od klawiatury już teraz!
źródło
Operatora przecinek jest sens swojego kodu.
Skutecznie ustawiasz,
this->listener = WSA_FLAG_OVERLAPPED;
co akurat jest poprawne syntatycznie.źródło
SOCKET
jest typedef dlaunsigned int
iWSA_FLAG_OVERLAPPED
jestint
dosłownym. GdybySOCKET
był synonimemint
, nie byłoby to nawet konwersją .struct __socket*
, mielibyśmy mniej błędów. Ale jest po prostu zbyt dużo kodu, który „wie”SOCKET
jest integralną częścią.Kompilator ocenia po kolei każdy punkt sekwencji w nawiasach, a wynikiem jest końcowe wyrażenie,
WSA_FLAG_OVERLAPPED
w wyrażeniu.Operator przecinka
,
to punkt sekwencji w C ++. Wyrażenie po lewej stronie przecinka jest w pełni oceniane przed wyrażeniem po prawej stronie. Wynik jest zawsze wartością po prawej stronie. Kiedy masz wyrażenie postaci (x1, x2, x3, ..., xn), wynikiem tego wyrażenia jest zawszexn
.źródło