이런 C/C++ 농담은 이해가 안 돼요.
thedailywtf.com 의 이 기사를 읽고 난 후, 나는 정말로 그 농담을 이해했는지 확신하지 못합니다.
거기에 어떤 사람이 코드를 바꿨다고 적혀있어요
int function()
{
int x;
char data_string[15];
...
x = 2;
strcpy(data_string,"data data data");
...
}
로.
int function()
{
int x = 2;
char data_string[15] = "data data data";
...
}
코드의 모든 곳에서 그리고 어떤 이유에서인지 실행 파일의 크기를 1개에서 2개로 부풀렸습니다(아니면 그렇지 않았을 수도 있습니까?).
분명히 저는 C/C++에 익숙하지 않아서 이런 농담을 들을 수 있지만, 이상하게 보이는 것은 두 번째 코드 목록이 적어도 학교에서 들은 바로는 "깨끗한" 것처럼 보인다는 것입니다. (변수를 초기화하는 것이 나쁜 것이 아니라 좋은 것이라는 것입니다.)
OIC, 이것은 소스-코드-턴 문제입니다.
언뜻 보기에는 두 양식이 동등합니다.두 번째 것은 더 멋져 보이지만 그들은 같은 일을 합니다.
하지만 인용된 페이지를 읽었습니다.
문제는 신입이 소스 나무를 마구 휘저었다는 것입니다.거대한 소스 트리를 트롤링해서 무의미한 변화를 만드는 것은 나쁜 형태입니다.물론, 한 가지 스타일이 다른 스타일보다 약간 낫겠지만, 실제로는 사람들이 영원토록 헤쳐 나갈 수 있도록 1,000 델타를 소스 코드 제어 시스템에 넣는 것이 정당화되기 전에 훨씬 더 나을 것입니다.
소스 릴리스였거나, 언급되지 않은 다른 복잡성으로 인해 많은 파일이 편집되어 배포가 확장된 것은 아닌지 의심됩니다.그 사이트에 기고한 글들은 꽤 많이 편집되어 있지만, 기본적으로 그 문제는 구체적인 내용 없이 이해할 수 있습니다.
스타일 변경을 위해 수많은 파일을 편집할 때 발생하는 문제점 중 하나는 의도치 않은 오류가 발생할 가능성이 높아진다는 것입니다.이 기회는 후배 개발자가 할 때 크게 증가합니다.경험자들에게도 머피의 법칙이 있습니다.그것이 출시 직전에 일어난다면 그것은 정말로 교수형 위반입니다.
컴파일러와 컴파일러 옵션에 따라서 이렇게 초기화를 합니다.
char data_string[15] = "data data data";
결과적으로 리터럴 데이터를 스택에 복사하는 이동 명령이 많이 발생합니다.
부르기strcpy
명령이 덜 필요합니다.
대규모 코드베이스 전체에서 이와 같은 작업을 수행하면 이진 크기가 크게 증가할 수 있습니다.
그리고 물론, 그는 가치를 더하는 데 시간을 쓰지 않았습니다.
두 번째 코드는 정말로 "cleaner"이지만, 기사가 대략적인 크기의 프로젝트로, 그렇게 리팩터링하는 것이 기껏해야 쓸모가 없고, 최악의 오류가 발생하기 쉽다고 생각하는 것은 말도 안 됩니다.
그러나 이러한 종류의 리팩토링은 a를 부풀리지 않습니다.exe 사이즈 양식 1~2 cds
여기서 다른 행동을 할 수가 없어요.LLVM으로 시도해 봤습니다. 반환 값에서 약간의 크라우프트만 추가하면 LLVM이 어떤 것도 최적화하지 않지만 생성된 코드는 다음과 같습니다.wtf
그리고.wtf2
완전히 똑같습니다.는 BAAAAD wtf는 BAAAD다입니다.
인풋
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int wtf(int X) {
int x;
char data_string[15];
x = 2;
strcpy(data_string,"data data data");
return 5*X+x+ data_string[X];
}
int wtf2(int X) {
int x = 2;
char data_string[15]="data data data";
return 5*X+x+ data_string[X];
}
int main(int argc, char **argv) {
printf("%d\n", wtf(atoi(argv[1]))+wtf2(atoi(argv[1])));
}
출력:
; ModuleID = '/tmp/webcompile/_3856_0.bc'
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32"
target triple = "i386-pc-linux-gnu"
@.str = internal constant [15 x i8] c"data data data\00" ; <[15 x i8]*> [#uses=3]
@.str1 = internal constant [4 x i8] c"%d\0A\00" ; <[4 x i8]*> [#uses=1]
define i32 @wtf(i32 %X) nounwind readnone {
entry:
%0 = mul i32 %X, 5 ; <i32> [#uses=1]
%1 = getelementptr [15 x i8]* @.str, i32 0, i32 %X ; <i8*> [#uses=1]
%2 = load i8* %1, align 1 ; <i8> [#uses=1]
%3 = sext i8 %2 to i32 ; <i32> [#uses=1]
%4 = add i32 %0, 2 ; <i32> [#uses=1]
%5 = add i32 %4, %3 ; <i32> [#uses=1]
ret i32 %5
}
define i32 @wtf2(i32 %X) nounwind readnone {
entry:
%0 = mul i32 %X, 5 ; <i32> [#uses=1]
%1 = getelementptr [15 x i8]* @.str, i32 0, i32 %X ; <i8*> [#uses=1]
%2 = load i8* %1, align 1 ; <i8> [#uses=1]
%3 = sext i8 %2 to i32 ; <i32> [#uses=1]
%4 = add i32 %0, 2 ; <i32> [#uses=1]
%5 = add i32 %4, %3 ; <i32> [#uses=1]
ret i32 %5
}
define i32 @main(i32 %argc, i8** nocapture %argv) nounwind {
entry:
%0 = getelementptr i8** %argv, i32 1 ; <i8**> [#uses=1]
%1 = load i8** %0, align 4 ; <i8*> [#uses=1]
%2 = tail call i32 @atoi(i8* %1) nounwind readonly ; <i32> [#uses=2]
%3 = getelementptr [15 x i8]* @.str, i32 0, i32 %2 ; <i8*> [#uses=1]
%4 = load i8* %3, align 1 ; <i8> [#uses=1]
%5 = sext i8 %4 to i32 ; <i32> [#uses=1]
%tmp2 = mul i32 %2, 10 ; <i32> [#uses=1]
%6 = shl i32 %5, 1 ; <i32> [#uses=1]
%7 = add i32 %6, 4 ; <i32> [#uses=1]
%8 = add i32 %7, %tmp2 ; <i32> [#uses=1]
%9 = tail call i32 (i8*, ...)* @printf(i8* noalias getelementptr ([4 x i8]* @.str1, i32 0, i32 0), i32 %8) nounwind ; <i32> [#uses=0]
ret i32 undef
}
declare i32 @atoi(i8*) nounwind readonly
declare i32 @printf(i8*, ...) nounwind
음, 기사 읽어보세요 :)
진짜 WTF는 그가 메모리 누수를 고치려고 할 때 이런 종류의 변화로 전체 솔루션을 건드린 것입니다.
또한 이와 같이 변경하는 것은 예제 파일보다 더 복잡한 다른 파일에서 버그를 수정/도입하는 것 외에는 큰 문제가 되지 않습니다.
네, 두 번째 코드가 더 깨끗하지만 컴파일러에 따라 더 많은 머신 코드가 나올 수 있습니다.이것은 전적으로 컴파일러에 의존적이지만, WTF 기사의 요점은 두 번째 경우에 컴파일러가 각 코드 조각에 대해 문자열/정수 값의 복사본을 할당하고 첫 번째 경우에는 프로그램당 한 번만 할당한다는 것입니다.
언급URL : https://stackoverflow.com/questions/1420009/i-dont-get-this-c-c-joke
'IT' 카테고리의 다른 글
C#에서 참조된 XSD에 대해 XML 유효성 검사 (0) | 2023.09.20 |
---|---|
오라클에서 날짜를 2개 빼서 시 분 단위로 결과를 얻는 방법 (0) | 2023.09.20 |
Git Submodule 포인터를 포함하는 저장소에 저장된 커밋으로 되돌리는 방법은 무엇입니까? (0) | 2023.09.20 |
regex로 그룹을 캡처하려면 어떻게 해야 합니까? (0) | 2023.09.15 |
싱글 페이지 애플리케이션이 블로그에 적합합니까? (0) | 2023.09.15 |