이 C ++ 기능의 이름은 무엇입니까?


82

일부 C ++ 코드를 작성하고 실수로 함수 이름을 생략했습니다 WSASocket. 그러나 내 컴파일러는 오류를 발생시키지 않았으며 SOCKET유효한 소켓 대신 정수 값 1 과 연결했습니다 .

문제의 코드는 다음과 같아야합니다.

this->listener = WSASocket(address->ai_family, address->ai_socktype, address->ai_protocol, NULL, NULL, WSA_FLAG_OVERLAPPED);

그러나 대신 다음과 같이 보였습니다.

this->listener = (address->ai_family, address->ai_socktype, address->ai_protocol, NULL, NULL, WSA_FLAG_OVERLAPPED);

다른 언어에서 오는,이 모양 이 같은 익명 형식의 일종이 될 수 있습니다. 기능이 실제로 기능인 경우 기능의 이름은 무엇입니까?

그 목적은 무엇입니까?

어디서부터 시작해야할지 모를 때 검색하기가 어렵습니다.


3
+1, 펍 퀴즈에 대한 좋은 질문 (또는 수수께끼를 잘하는 사람을 고용하고 싶어하는 회사에 대한 끔찍한 인터뷰 질문).
Bathsheba 2014

8
쉼표 연산자에 대한 Wikipedia 기사 링크 . FWIW, 일반적인 용도 중 하나는 (int i = 0, j = 0; i <10; ++ i, --j) ...` 에 대한 for루프 * 반복 표현식 에서 두 가지 부작용을 얻는 것입니다 , ala .`
Tony Delroy

1
@ MichaelJ.Gray 기술적으로 당신은 틀 렸습니다. 동작을 덮어 쓰지 않습니다. Imagin : i=0;j=0;x=i++,j=6;x와 j는 6 것 그리고 난의 행동하는 그것이 0으로 남아있을 것입니다 덮어 것 ++ 그러나 각 문이 호출됩니다과에 도달 한 후 경우 어차피 1. 것이다 ,단지 모든 확장을 폐기 얻을하고 다음 의사 sequencepoint가 호출됩니다. 따라서 첫 번째 =는 마지막 이후에 부품을 ,할당하지만 각 포인트가 호출됩니다. 어쨌든 : 컴파일러가 함수 선언의 재정의에 대해 경고하지 않고 대신 코드를 다른 동작으로 변경하는 이유를 알 수 없습니다.
dhein

5
경고가 설정된 적절한 컴파일러를 사용하는 경우 예를 들어 다음 gccg++같은 -Wall옵션을 사용하여 이러한 이상한 코드에 대해 경고합니다 .warning: left-hand operand of comma expression has no effect [-Wunused-value]
Sam Watkins

3
그래서 제 생각에이 질문에 대한 가장 좋은 대답은 "항상 경고를 활성화하십시오"입니다. 그러면 컴파일러 자체가 오류가 있음을 설명하고 수행 한 작업을 알려줍니다. 이 답변은 다른 많은 문제도 해결할 수 있습니다.
Sam Watkins 2014

답변:


151

쉼표 연산자 †는 왼쪽을 평가하고 그 값을 버리고 결과적으로 오른쪽을 산출합니다. WSA_FLAG_OVERLAPPED1이고 이는 표현식의 결과입니다. 다른 모든 값은 버려집니다. 소켓이 생성되지 않습니다.


† 과부하가없는 경우. 예, 과부하가 걸릴 수 있습니다. 아니요, 과부하를 일으키면 안됩니다. 지금 당장 키보드에서 떨어져!


9
+1, 부스트 스피릿은 쉼표 연산자를 매우 효과적으로 오버로드하지만 규칙에 대한 매우 외로운 예외 입니다. 하지 마십시오 .
Bathsheba 2014

2
@Bathsheba Boost.Assign도 쉼표 연산자를 오버로드하지만 C ++ 11 이후로 누가 사용합니까?
rubenvb 2014

39
그러나 당신은 강력한 쉼표가 얼마나 무서운지에 대한 최고의 설명을 가지고있었습니다. 용서하지 않고 비웃음으로 가득 찬, 그것은 그 행동에 대한 수치심없이 나를 쳐다 보면서 몇 분 동안 내 코드를 괴롭혔다.
Michael J. Gray


1
@ R.MartinhoFernandes-Eigen은 또한 쉼표 연산자를 매우 효과적으로 오버로드합니다. 샘플 사용법 은 이 SE 질문 을 참조하십시오 .
David Hammen 2014

22

쉼표 연산자는 코드를 이해하고있다.

당신은 this->listener = WSA_FLAG_OVERLAPPED;단지 구문 적으로 유효한 것을 효과적으로 설정 하고 있습니다.


3
구문 적으로 유효 할뿐만 아니라 Windows API가 형식에 안전하지 않기 때문에 유효한 변환이기도합니다.
MSalters

5
@MSalters는 POSIX가 그 점에서 훨씬 더 낫다는 것이 아닙니다
chbaker0

1
이것이 단일 인수로 호출 가능한 생성자가 명시 적 이어야하는 이유입니다 . 그러면 컴파일러 오류가 발생하고 개발자는이 기괴한 구조를 다시 살펴볼 기회가있을 것입니다.
Matthieu M.

@MSalters 음, SOCKET에 대한 형식 정의입니다 unsigned int, 그리고 WSA_FLAG_OVERLAPPED입니다 int리터럴. 에 SOCKET대한 동의어 가 있었다면 변환int 도 아닐 것 입니다.
Joker_vD 2014

1
@Joker_vD : 그렇습니다. 를위한 typedef로 만들었 더라면 struct __socket*버그가 적을 것입니다. 그러나 "알고있는"코드가 너무나도 많습니다 SOCKET.
MSalters

21

컴파일러는 괄호 안의 각 시퀀스 포인트 를 차례로 평가 하고 결과는 표현식의 최종 WSA_FLAG_OVERLAPPED표현식입니다.

쉼표 연산자 ,는 C ++의 시퀀스 지점입니다. 쉼표 왼쪽에있는 식은 오른쪽에있는 식보다 먼저 완전히 평가됩니다. 결과는 항상 오른쪽의 값입니다. (x1, x2, x3, ..., xn) 형식의 표현식이있는 경우 표현식의 결과는 항상 xn입니다.


거기에 설명을 추가하면 더 의미가 있습니다. 처음에는 시퀀스 포인트 문제의 관련성을 잘 이해하지 못했습니다.
Michael J. Gray
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.