게임코디 게임코디 연구소 GCGC 프로카데미 교육센터   회원가입 회원등급 실무자 인증 공지사항 RSS
게임프로그래머 만담 커뮤니티 베타게시판 :   지금은 개발중  |             |   무리수 건의함  |  이미지 HDD  |
게임개발자 실시간 만담
   로그인이 안돼요 자동 로그인


새로운 댓글
  안녕 ~ 게임코디 ㅋㅋ
  막아야 하는데 귀찮아...
  답글은 달고 봅니다 ㅋ...
  ㅋㅋㅋㅋㅋㅋ 이러지 ...
  이러지 마십쇼 아직 작...
  아 포인트는 어제 19시...
  두구두구두구두구....
  오!
  누군가 전염병주식회사...
  앗 아앗...
  16200원
  삼성전자우KODEX200KO...
  오오 마토찡의 게임
  되는걸로 알고있습니다...
  코스피 1680찍고 말...
  2019버전이긴 한데, ...
  흠... 과연
  올해만 버티시고5기가/...
  호우 감사함돠
  답변들 감사합니다. dl...
  .....
  비쥬얼이 재미있어보이...
  글로벌 판데믹으로 변...
  해외 직구 배송비 포함...
  ㅎㅎ 그런가요? 감사합...
  아... 사놓을걸...미...
  저도 유투브 보다가 이...
  마감되었습니다. 감사합...
  외부로부터 의도하지 ...
  쩐이 없는거 같어요총...

# 여기는 읽기 전용의 구 '게임코디 1st' 입니다

# 우리는 이제 게임코디 2nd 로 갑니다. https://gamecodi.com

게임 프로그래머의 만담은 새로운 '게임코디 2nd' 에서 진행됩니다.

개발만담 - 개발,업무,우리의 밥벌이와 관련된 만담 게시판.

Loading...
C++표준을 따르면서 buffer에 쓰고 읽는법. 제대로 알고 계신가요?
  retro 
작성 : 2020-02-10 17:31:36    |    조회 : 2,313
    1       
  

C++에서 buffer(내부가 char, unsigned char, 혹은 std::byte로 이루어진 array 혹은 heap에 할당된 array) 에 C++ 표준을 어기지 않으면서 데이터를 쓰거나 읽고싶습니다. 어떻게해야될까요?

클릭시 이미지 새창.
클릭시 이미지 새창.

Q: 간단하게 이렇게하면 되지않을까요?

안됩니다. 위 코드는. C++ 표준을 어기게됩니다.

Q: 에이 설마요, 못믿겠는데요?

같이 C++ 표준을 확인해봅시다.

클릭시 이미지 새창.


표준에선 객체의 lifetime은
1. definition (int a; // <- 이런식의 정의)
2. new-expression (placement new, heap할당할때 쓰는 new 둘다)
3. union멤버중 하나를 implicitly change할때
4. temporary object가 생성될때
중 하나의 과정을 거쳐야만 시작이 된다고 합니다.

객체의 lifetime을 시작하는 위에 나열된 4개중 어느것의 과정을 거치지 않은곳을 접근하는 행위는 undefined behavior입니다. (int*로 어딘가를 가르키고있는데 int 객체가 없는곳)

위 예제 코드에 buf*가 가르키는것은 unsigned char[4] 입니다. 다른 타입으로 C-style cast를 하든 reinterpret_cast를 하든 buf가 무엇을 가르키는지는 바뀌지 않습니다.

Q: Undefined behavior가 그래서 정확히 뭡니까?

UB를 invoke하는 코드를 컴파일할 경우 컴파일러는 자기 맘대로 코드를 짠 사람의 의도와 전혀상관없는 바이너리를 생성할수있습니다. (aggressive-optimization중에 의도된 코드와 다른 outcome이 나온다던지, crash, memoryleak, 등 무엇이든요.) 물론 아직까진 현실적으로 위의 코드에서 프로그램이 뻑나거나 메모리 릭이생기는일은 없다고봐도 무방합니다.

Q: 아니그러면 어떻게해야되나요?

클릭시 이미지 새창.
클릭시 이미지 새창.

write에선 memcpy를 불러주시고, read에선 위에 객체가 생성되는 과정중 1에 해당하는 T ret_; 을 선언한뒤 ret_에 memcpy 하시면 됩니다. 물론 typename T 가 std::is_trivially_copyable_v<T> == true 에 부합해야합니다.

위를 좀더 편하게(type-punning을 가능하게)하는 함수가 C++20에 들어옵니다. 무려 constexpr 함수로요.

클릭시 이미지 새창.

constexpr memcpy는 컴파일러 매직이 필요하지만 그냥 memcpy로도 c++11, 14, 17에서 표준을 지키면서 type-punning이 가능하게 해줍니다.

Q: 근데 memcpy하면 그냥 일반 포인터 캐스팅해서 읽는거보다 느리지않나요?

글쎄요, 같이 확인해볼까요?

클릭시 이미지 새창.
클릭시 이미지 새창.
클릭시 이미지 새창.
세 major 컴파일러들 다 no-op으로 optimize 해줍니다.

Q: 네트워크나 i/o 추상화해준 라이브러리 대부분 뜯어보면 저런코드들 많은데 여태 아무런 문제 없었어요. 상관 없는거 아닌가요?

개인적인 의견으론 오히려 표준에서 정의되지 않은 코드가 지금 버그를 일으키지 않는게 더 위험하다고 생각이 됩니다. 시간이1년 혹은 2년 혹은 10년 후, 어느날 갑자기 컴파일러 벤더들이 UB trigger 하는 코드들을 적극적으로 optimize하려하는 컴파일러들을 릴리즈하게되면 그때 버그잡는건 상당히 어렵겠죠. 플랫폼 종속성문제도 생길거구요.

긴글 읽어주셔서 감사합니다.


edit : 아 그리고 빼먹은게 있는데 gcc, clang에서는 -fno-strict-aliasing 커맨드를 컴파일할때 넘겨주면 strict-aliasing 룰을 위반하는 코드라도 안전한 바이너리가 생성됩니다. 물론 위 상황에서도 제대로 동작해야되기때문에 최적화를 하겠죠. 제가알기로 MSVC는 그런커맨드는 없는데 본인들 <Windows.h> 헤더같은곳에 strict-aliasing을 위반하는 코드들이 많아서 아직 gcc나 clang처럼 위 상황에서 optimize할 엄두는 아직은 못낼거에요.

그리고 C++23에 나오는 std::start_lifetime_as<T>는 여기서 다루지 않았는데
C++23이되면 malloc, memcpy, memmove, std::start_lifetime_as<T> 네 함수도 객체의 lifetime을 시작할수있게 표준에 건의가된 상태입니다.



  
괴발개발


(대충 완벽히 이해한 표정)
2020-02-11
11:09:08

  
smileeagle


공부 열심히 하시는군요 보기 좋네요
2020-02-11
11:19:54

  
AYA


잘 읽었습니다.
2020-02-11
12:16:13

  
폴리모프


아~ 완벽히 이해했어!
2020-02-11
15:34:39

  
베이스군


클릭시 이미지 새창..
2020-02-12
09:14:44

  
뎐삼


클릭시 이미지 새창..
2020-02-12
10:00:29

  
DB하는조씨


반성...
간단해 보이는것도 파면 파이군요;;
2020-02-17
09:32:38



목록보기  |  
SORT :: |  번호순  |  최근댓글  | HIT
notice
■■ 개발만담 게시판 안내 ■■  [7]
   게임코디 11/07/04 4572
4943
게임 주제의 KBS 다큐 두 편  [1]   
  술취한아저씨
20/03/15 2804
4942
visual studio 2017 이거 옵션 뭘 바꿔야 할까요?  [7]   
  아쥬
20/03/08 2628
4941
리포지드... 보고 있나? 이것이 [ 리메이크 ] 다!  [2]   
  노코드
20/03/08 3254
4940
VSCode C# Update 주의  [3]   
  시니컬춥스
20/03/06 3015
4939
NDC 20 행사 잠정연기 ㅜㅜ  [2]   
  게임코디
20/03/05 2370
4938
블소 프론티어  [7]   
  뎐삼
20/03/05 2314
4937
std말고 간단한(?) 컨테이너들 모은 라이브러리 (오픈소스) 혹시 없을까요...  [9]   
  아쥬
20/03/02 2802
4936
게임 개발자 학습 로드맵 (GitHub 펌)  [1]   
  장찌루
20/02/28 2966
4935
두 유 노우 재택근무 프로그래머 ?  [5]   
  노코드
20/02/25 2367
4934
재택근무 시행 게임사  [16]   
  뎐삼
20/02/25 2550
4933
프로그래머 실무 면접에 관한 동영상 링크 투척해요~~  [6]   
  ProgC
20/02/25 2638
4932
중견회사들은 신작게임 안 만드나요?  [8]   
  imays
20/02/24 3092
4931
근본없는 블렌더 -5편- retopo     
  뎐삼
20/02/24 829
4930
근본없는 블렌더 -4편- 채색     
  뎐삼
20/02/24 1918
4929
근본없는 블렌더 -3편- 버텍스 직접 편집  [1]   
  뎐삼
20/02/22 1372
4928
근본없는 블렌더 -2편- 스컬프팅     
  뎐삼
20/02/22 1248
4927
근본없는 블렌더 -1편- 설치 및 기본조작  [2]   
  뎐삼
20/02/21 1710
4926
비쥬얼스튜디오에 build clean 할 때...     
  아쥬
20/02/21 519
4925
안드로이드에서 네이티브 코드로 IPC사용시 대량의 데이터 처리  [6]   
  아쥬
20/02/20 998
4924
2020 NDC 발표자를 모집합니다  [4]   
  게임코디
20/02/18 1612
4923
언리얼 빌드후, 안드로이드에서 크래시 확인하는 좋은 방법이 있을까요?  [4]   
  아쥬
20/02/13 1283
4922
쌩초보주의)) 유니티 모바일과 컴퓨터 개발이 차이가 있나요?  [2]   
  김김김민
20/02/13 1435
4921
개발 소스의 해킹보안에 대해 질문드립니다.  [10]   
  군림주먹
20/02/12 2662
4920
APK 앱서명의 보안성에 대해 궁금합니다.  [1]   
  kachuuu
20/02/11 733
4919
게임서버프로그래밍 교과서에 첨부된 코드에 대한 주의사항  [4]   
  imays
20/02/11 1455
C++표준을 따르면서 buffer에 쓰고 읽는법. 제대로 알고 계신가요?  [7]   
  retro
20/02/10 2313
4917
Creator's star  [3]   
  데미데루스
20/02/09 861
4916
리눅스 epoll 에서 epolloneshot, epollexclusive 플래그...  [10]   
  retro
20/02/09 1658
4915
언리얼에서 안드로이드 빌드할 때, 플러그인 낑가 넣으면...  [1]   
  아쥬
20/02/09 751
4914
프라우드넷  [8]   
  발코더6
20/02/07 1601
4913
이세계 카페에서 바리스타가 되는 게임! Coffee Talk     
  술취한아저씨
20/02/02 1303
4912
개발자 번아웃 대처방법의 모든 것  [4]   
  노코드
20/01/29 2676
4911
앱스토어 검색어에 검색이 안됩니다.  [1]   
  닥터이블
20/01/26 725
4910
Vulkan과 메탈  [4]   
  그래픽스어린이
20/01/23 2952


목록보기  |   다음페이지  |   1 [2][3][4][5][6][7][8][9][10]..[142] [다음 10개]



게임코디 GAMECODI , 게임 프로그래머 만담 커뮤니티

게임코디 소개     |      크라우드펀딩 후원자     |      관리실 연락처     |