2015-01-17 4 views
0

이 무엇을 의미합니까 내가 C에서 정말 고급 아니라고하지만 코드은 C에서이 권리가 있습니까?

ssize_t ret = 0; 
ret += sprintf(buf + --ret, "\n"); 

의 조각이 발견 (변수 컴파일러 오류에 작업을 금지)?
그리고이 경우 실제로 --ret을 할 수 있습니까?

+1

여기서'buf' ...는?, 왜'--ret'을 할 수 없습니까? –

+0

네, 아마도'ssize_t'를 미리 감소시킬 수 있습니다. 코드가 의미하는 바를 정확히 이해하려면 더 많은 문맥이 필요합니다. –

+0

이 코드는 현재 buf 포인터 앞에 "\ n"문자열을 넣습니다. – user590028

답변

7
ret += sprintf(buf + --ret, "\n"); 

위의 내용은 Undefined Behavior (UB)이므로 아무런 의미가 없습니다.

따라서 대답은 강조 표시입니다. 아니요!.

왜?

ret이 두 번 쓰여지며 중간에 시퀀스 포인트가 없습니다.

은 ( ret의 실제 증가분은 --ret의 값을 결정하는 데 읽은 후 언제든지 일어날 수 있으며 폐쇄 세미콜론 전에.
을 따라서, 할당 ret += ...하여 변경과 충돌. 또한
--ret에서의 ret ret 업데이트 ret += ...에서 충돌의 판독). 제쳐두고, C++로의

을 대신 시퀀스 점 C++ 11 (서열)이 잘 정의 될 수 있기 때문이다.

+2

이것은 잘못되었거나 최소한 불완전합니다. 전형적인 문제는 아니며'sprintf (...)'가 함수 호출이기 때문에 함수가 호출되기 직전에 시퀀스 포인트가 있으며, 'ret'의 첫 번째 수정은 그 시퀀스 이전에 발생한다고 합리적으로 생각할 수도 있습니다 두 번째 수정은 해당 시퀀스 포인트 이후에 발생합니다. 그러나,'sprintf'가 호출되기 전에'ret'의 추가 * read *가있을 수 있습니다. 그리고 * 확실히 * 정의되지 않은 동작을 일으 킵니다. 또한 이론상으로'sprintf'는이 경우에는 어떤 시퀀스 포인트도 갖지 않는 매크로로 구현 될 수 있습니다. – hvd

+0

@hvd : 흠, 내 설명이 약간 얇다고 썼다. 아직도'sprintf'가 매크로일까요? 먼저 들었습니다 ... – Deduplicator

+1

예, C++과 달리 C는 라이브러리 기능을 매크로로 구현할 수있게 해주 었으며, 역사적으로 일반적으로 'isupper'와 같은 함수에서 일반적으로 수행되었습니다. 그것은 'sprintf'를 위해 할 수있는 일은 극히 드뭅니다. 7.1.4 : "[...] 헤더에 선언 된 함수는 헤더에 정의 된 함수와 같은 매크로로 추가 구현 될 수 있습니다. [...]" – hvd