꽤 지난 소식이지만, VS2013의 Community version이 무료로 공개되었습니다.


Free Dev Tools VS2013 Community

http://www.visualstudio.com/en-us/products/visual-studio-community-vs


Unity, Node.js 등 다양한 언어의 개발환경으로도 자주 선택되는 VS2013의 무료 버전이 공개되었습니다.


개인적으로도, Visual Studio 5.0 시절부터 단연 최고의 개발 도구라 여겨왔었는데, 이제는 무료 버전과 함께, 그리고 다양한 플러그인과 디바이스를 지원해줌으로써 훨씬 강력한 IDE로 등극하지 않았나 싶습니다.


저도 집에서 VS2013을 쓰는데요, MFC까지 지원되는 버전인만큼 기존 C++ IDE로써 사용하시던 분들도 굳이 상용버전을 사용하지 않고도 각종 프로그램 개발을 하실 수 있겠네요.


추천드립니다.


Everything you need, all in one place

Tools

Tools

Designers, editors, debuggers, profilers - all packaged up in a single environment.
Languages

Languages

Code in C++PythonHTML5,JavaScript, and of course C#,VB, and F#.
Web

Web

Extensive web support forASP.NETNode.js, andJavaScript

Devices

Tools for Apache Cordova andUnity to reach even more platforms















Posted by 엘키 엘키

댓글을 달아 주세요


Features

Highlights:

  • Open Source! GPLv3, no hidden costs.
  • Cross-platform. Runs on Linux, Mac, Windows (uses wxWidgets).
  • Written in C++. No interpreted languages or proprietary libs needed.
  • Extensible through plugins

 

Compiler:

  • Multiple compiler support:
    • GCC (MingW / GNU GCC)
    • MSVC++
    • clang
    • Digital Mars
    • Borland C++ 5.5
    • Open Watcom
    • ...and more
  • Very fast custom build system (no makefiles needed)
  • Support for parallel builds (utilizing your CPU's extra cores)
  • Multi-target projects
  • Workspaces to combine multiple projects
  • Inter-project dependencies inside workspace
  • Imports MSVC projects and workspaces (NOTE: assembly code not supported yet)
  • Imports Dev-C++ projects

 

Debugger:

  • Interfaces GNU GDB
  • Also supports MS CDB (not fully featured)
  • Full breakpoints support:
    • Code breakpoints
    • Data breakpoints (read, write and read/write)
    • Breakpoint conditions (break only when an expression is true)
    • Breakpoint ignore counts (break only after certain number of hits)
  • Display local function symbols and arguments
  • User-defined watches (support for watching user-defined types through scripting)
  • Call stack
  • Disassembly
  • Custom memory dump
  • Switch between threads
  • View CPU registers

 

Interface:

  • Syntax highlighting, customizable and extensible
  • Code folding for C, C++, Fortran, XML and many more files.
  • Tabbed interface
  • Code completion
  • Class Browser
  • Smart indent
  • One-key swap between .h and .c/.cpp files
  • Open files list for quick switching between files (optional)
  • External customizable "Tools"
  • To-do list management with different users

And many more features provided through plugins!

 

출처: <http://www.codeblocks.org/features>

 

Windows, linux, mac os x 플랫폼을 지원하고, 대다수의 메이저 컴파일러를 지원합니다. 하지만 gcc 사용하지 않을거라면 굳이 무료 버전도 배포중인 MSVC 사용하지 않을 이유가 없기에… GCC용으로 사용하시길 권장합니다.

 

기존 MSVC Dev-C++ project 파일도 import 되기 때문에 컨버팅 비용도 상대적으로 적습니다. 물론 platform independency 코드를 작성하지 못한 코드는 모두 작성 해야겠지만요.

 

Code::blocks download

http://www.codeblocks.org/downloads/26

 

GCC에서 boost 사용하게 되면 platform independency 코드를 작성할 있게 됩니다.

아래 링크는 code::blocks boost 빌드하는 방법입니다.

 

Code::blocks for boost

http://stackoverflow.com/questions/13301089/how-do-i-build-boost-libraries-on-codeblocks-windows



Posted by 엘키 엘키

댓글을 달아 주세요

다운로드 받아 설치 목록

 


환경 변수 설정 주의 사항

  • JDK를 제외하고는 특정 폴더안에 배치해두었다는 전제로 batch 파일을 작성했습니다.
  • 다른 버전을 설치하신다면 반드시 batch 파일 내용도 수정해주셔야 합니다.

환경 변수 설정 배치 파일
  • setx ANDROID_SDK_ROOT "%cd%\adt-bundle-windows-x86_64-20140702\sdk"
  • setx ANT_ROOT "%cd%\apache-ant-1.9.4\bin"
  • setx NDK_ROOT "%cd%\android-ndk-r10c"
  • setx NDK_MODULE_PATH "%cd%\cocos2d-x-3.3rc0;%cd%\cocos2d-x-3.3rc0\cocos\2d\platform\android"
  • setx CLASS_PASS ""
  • setx JAVA_HOME "C:\Program Files\Java\jdk1.8.0_25"
  • setx PATH "%PATH%;%cd%\cocos2d-x-3.3rc0\tools\cocos2d-console\bin" 



cocos2d-x_setx.bat



setup.py 스크립트 

환경 변수를 등록해두었다면, 스크립트 파일을 실행하면 자동으로 설치가 된다.

command 창을 띄우고 cocos를 입력해 setup이 완료되었는지 확인하자.


'C++ > Rendering' 카테고리의 다른 글

cocos2d-x 3.3rc0 설치하기  (0) 2014.12.09
초당 프레임에 대한 썰  (0) 2013.12.10
[리소스] 스프라이트 자료  (0) 2013.11.27
클라이언트 테스트  (0) 2009.12.29
SDL - Simple Directmedia Layer  (0) 2008.09.24
Posted by 엘키 엘키
 TAG Cocos2d-x

댓글을 달아 주세요

이 글은, c++을 기반으로 작성되었지만 예외 처리 기능 (try-catch, try-except 등)을 가진 모든 언어에 적용 되는 내용입니다. 파일에서 데이터를 읽는 코드를 작성해봅시다. c++로 작성해보겠습니다.
int _tmain(int argc, _TCHAR* argv[])
{
	FILE* fp;
	fp = fopen("test.bin", "rb");

	if(fp == NULL)
	{
		// 예외 처리
		return 1;
	}

	char buffer[512] = {0, };
	fread(buffer, 512, 1, fp);
	return 0;
}
대부분 위 코드처럼 작성하게 됩니다. 위 코드에서 누락된 예외처리 발견하신분? 예. 바로 fread 부분입니다. 

항목이 읽히지 않았을 때, fread는 0을 리턴하고, 0을 리턴했을 때에는 로그를 찍는다거나 등의 예외처리를 해주어야 파일을 잘못 읽었는지를 조기에 발견 할 수 있습니다. 

헌데 대부분의 수많은 예제는 첫 예제처럼 fread에 대한 검사는 이루어지지 않습니다. 바로 이 부분이 쉽게 놓치는 첫 감염입니다. 

감염을 조기에 발견하지 못하면, 숙주를 찾기 어려워지고 숙주를 찾지 못하면 전염병처럼 퍼지게 됩니다. 위 코드의 모범적 예외 처리 방식은 아래와 같습니다.
int _tmain(int argc, _TCHAR* argv[])
{
	FILE* fp;
	fp = fopen("test.bin", "rb");

	if(fp == NULL)
	{
		// 예외 처리
		return 1;
	}

	char buffer[512] = {0, };
	int read_count = fread(buffer, 512, 1, fp);
	if(read_count == 0)
	{
		// 예외 처리
		return 2;
	}
	return 0;
}
이렇게 되어야 buffer의 데이터가 유효하게 로직으로 전달되었는지 검사할 수 있습니다. 

혹자는, 컨텐츠 코드에서 방어적으로 데이터가 유효한지 검증해야 되는게 아니냐라고 하실 수도 있습니다. 

하지만, 그 당연하다 여겨지는 전치검사/후치보장은 막상 그렇게 당연하게 여겨지지 않는게 현실입니다. 

심지어 클래스 내부 멤버에 대해선 전치검사 대상으로 여겨지지 않는 경우가 태반입니다. 게다가 작성하는 API 함수 및 프로젝트에서 구현한 함수마다 사용법및 예외 처리 방식을 검토하는 일은 매우 번거롭고 실수가 있을 수 밖에 없죠. 

같은 프로젝트내에 리턴값 및 예외 처리 방식이 조금만 다르게 작성 (WIN32 API에서의 DWORD형의 결과값과 COM에서 HRESULT 값이 주로 그런 케이스. 어떤 매크로로 검사해야될지부터 혼동이 옴.) 된 걸로도 충분히 혼란스러운데, 여러개의 서드파티 솔루션까지 사용하는 규모가 큰 프로젝트의 경우 그 피로도가 장난이 아니죠. 

 그 대안으로 대부분의 언어에서는 예외 처리 기능을 지원합니다. c++의 경우 try-catch(try-except는 SEH)가 그 역할을 하는데요, boost나 STL의 경우에는 내부적으로 오류를 감지하면 throw로 예외를 던지고 있습니다. 말로만 하면 감이 안오실테니 코드로 보여드리겠습니다.
int _tmain(int argc, _TCHAR* argv[])
{
	try
	{
		FILE* fp;
		fp = fopen("test.bin", "rb");

		if(fp == NULL)
		{
			throw std::exception("file open failed.");
		}

		char buffer[512] = {0, };
		int read_count = fread(buffer, 512, 1, fp);
		if(read_count == 0)
		{
			throw std::exception("file data read failed.");
		}
	}
	catch(const std::exception& e)
	{
		std::cout << e.what() << std::endl;
		return 1;
	}
	return 0;
}
사용자 정의 exception 클래스를 이용할 수도 있지만, 여기선 쉬운 예제를 위해 std::exception 클래스를 통해 예외처리를 했습니다. 사실 이렇게 간단한 예제로는 예외처리가 뭐가 더 낫다는건지 감이 잘 오지 않습니다. 저도 그랬으니까요. 자~ 코드가 복잡해집니다. 다양한 기능이 붙고, 추상화니, 메시지 핸들러니 각종 쌈박한 로직을 구현해두었습니다. 만들다보니 기능이 붙고 붙네요. 외부 라이브러리도 붙었습니다. 정규식은 boost쓰고, 컨테이너는 stl 쓰고, json은 json spirit, xml은 tinyxml 을 붙였군요. 제가 이 글을 쓰고자 했던건 사실 tinyxml 때문이었습니다. tinyxml 물론 잘 만들어진 라이브러리입니다. 저도 아주 잘 쓰고 있고요. 헌데 이 tinyxml에서 문제가 하나 있었습니다.
TiXmlElement* pNickname = pPlayerElem->FirstChildElement("nickname");
if (pNickname  == NULL)
	return false;

std::string nickname = pNickname >GetText();
문제가 된 부분이 보이시나요? 전 몇번이나 코드를 훓어보던 중에야 원인을 찾을 수 있었습니다. 

원인은 pNickname >GetText() 이 함수가 문제였습니다.

위 코드는 nickname을 문자열형으로 읽어내는 코드입니다. 위 코드는 정상적으로 데이터가 포함되어있을 땐(<Nickname>엘키</Nickname>) 문제가 없습니다.   헌데 만약 이렇게 비어있는 값(<Nickname></Nickname>)일 때 읽는다면? 문제가 생겼습니다. 


비어있을 때 문제가 생긴다는 것도, 코드를 자세히 들여다 보고 나서야 확인한 것이지, 덤프를 본 직후에 바로 알아볼 순 없었어요. 


한 줄 한 줄 코드를 검토하며 함수 내부를 들여다 본 순간… 아차 싶었습니다.

const char* TiXmlElement::GetText() const
{
	const TiXmlNode* child = this->FirstChild();
	if ( child ) {
		const TiXmlText* childText = child->ToText();
		if ( childText ) {
			return childText->Value();
		}
	}
	return 0;
}
child->ToText() 함수가는 내부에 포함된 데이터가 비어있을 때 NULL이 반환되고, 이어 함수 최하단에서 return 0; 코드를 타 NULL 포인터가 반환되었습니다. 

사실 이 함수가 반환타입이 const char* 인 만큼 return ""; 으로 빈 문자열을 반환할 줄 알았습니다.  하지만 빈문자열과 child가 없는 등의 Text화 실패에 대한 상황을 구분하기 위해 return 0; 으로 처리하고 있더군요. API를 꼼꼼하게 체크해보지 못한 개발자의 잘못도 있지만 구현상의 애매모호함도 엄연히 존재한다고 봅니다. 

1. 오류 상황과 데이터가 없음을 모두 return 0; 즉 NULL 포인터로 반환하고 있는 문제
2. const char*형은 문자열형만 반환될뿐 사실은 pointer의 개념보다는 문자열 첫 주소가 반환된다는 의미로도 인식되어, NULL 포인터가 반환될 거라 인식하기 어려운 문제를 가지고 있는것이죠.

결과적으로 GetText() 함수의 구현 코드를 보니 NULL 포인터가 반환되는지 검사해주어야 했습니다.

위 코드를 예외처리해봅시다.
TiXmlElement* pNickname = pPlayerElem->FirstChildElement("nickname");
if (pNickname  == NULL)
	return false;

if(pNickname->GetText() == NULL)
	return false;

std::string nickname = pNickname >GetText();

TiXmlElement* pUserID = pPlayerElem->FirstChildElement("user_id");
if (pUserID  == NULL)
	return false;

if(pUserID >GetText() == NULL)
	return false;

std::string user_id= pUserID>GetText();
이렇게 해주어야합니다. GetText를 사용하는 코드가 많으면 많을수록 if문은 늘어납니다. 물론 위의 if문을
if (pUserID  == NULL || pUserID >GetText() == NULL)
	return false;
or 연산으로 수정할수야 있겠지만, 그렇다손쳐도 GetText() 하는 함수마다 체크해주어야 함은 변함이 없습니다.
const char* TiXmlElement::GetText() const
{
	const TiXmlNode* child = this->FirstChild();
	if ( child == NULL) 
	{
		throw std::exception("TiXmlElement::GetText() FirstChild is NULL");
	}

	const TiXmlText* childText = child->ToText();
	if ( childText == NULL) 
	{
		throw std::exception("TiXmlElement::GetText() ToText Failed.");
	}
	return childText->Value();
}
이렇게 코드를 작성했다면 어떨까요?
try
{
	TiXmlElement* pNickname = pPlayerElem->FirstChildElement("nickname");
	if (pNickname  == NULL)
		continue;

	std::string nickname = pNickname >GetText();

	TiXmlElement* pUserID = pPlayerElem->FirstChildElement("user_id");
	if (pUserID  == NULL)
		return false;

	std::string user_id= pUserID>GetText();
}
catch(const std::exception& e)
{
	std::cout << e.what() << std::endl;
	// 일괄적인 예외 핸들링
	return false;
}

만약 try안에서 호출된 다른 함수에서 throw가 존재한다해도 코드의 흐름을 멈추고, 원인을 알아낼 수 있게 됩니다. 


이렇게 되면 예외처리를 일괄적으로 할 수 있고, 코드의 흐름을 중단하는 역할도 맡길 수가 있습니다. 


 보통 외부 라이브러리 함수에서 크리티컬한 상황이 발생했을 경우라거나, 유틸리티 함수등에서의 실패를 리턴값으로 반환하곤 하는데, 이보다 더 강하게 코드의 진행을 중지 시키고 싶을 때 (2차 감염을 막고, 현재 상황의 위험성을 알리기 위해서 주로 이렇게 하죠) 라고 볼 수 있습니다. 


리턴값은 그 함수를 사용하는 코드마다 체크 로직과 핸들링 로직을 구현해주어야 합니다. 


이에 비해 예외 처리는, 적절한 위치에 try-catch로 묶어주기만해도 throw로 던져진 예외를 핸들링 할수가 있게 됩니다. 


물론 모든 코드가 그렇게 예외처리를 하는 것은, 코드의 흐름을 원치 않는 곳에서 중단 시키기 때문에, 상황에 따라 국소적인 코드마다 try-catch 핸들링을 해주어야 하는 부작용도 있긴하지만, 순작용이 훨씬 많은 예외 처리 방식입니다. 

 심지어 이는 C++에 국한된 것이 아닌, 대다수의 언어에서 지원되는 예외처리 방식이므로 한번 몸에 익혀두시면 두고 두고 활용하시기에 좋습니다. 


C++도 표준 라이브러리들은 대부분 throw로 예외처리를 하기 때문에 try-catch로 예외처리를 할수있고, ruby등의 기타 스크립트 언어들도 내부 함수 예외를 try-catch로 핸들링 할 수 있습니다. 


try-catch 적용시 많이들 어렵게 생각하시는 점은, 어디서 부터 어디까지 try-catch로 감싸도 되는가에 대한 고민이라고 생각하는데요, 이는 boost나 stl등 내부적으로 throw를 사용하고 있는 함수들 부터 적용해보시면 어렵지 않게 적응하실 수 있습니다.


코드의 흐름을 제어하고, 일반화된 오류 처리를 도와주는 예외처리. 적극적으로 써보시면 어떨까요?




Posted by 엘키 엘키

댓글을 달아 주세요

흔히 말하는 초당 프레임을 세부적으로 나누면 입력, 로직, 렌더링으로 나뉘어집니다.


그리고 그것들을 일치 시키는 경우도 있지만 분리하는 경우도 존재합니다.


여러가지 이유로 로직 프레임은 밀려서라도 처리를 해야 되는 경우, 저 사양이나 평소보다 급격히 많은 오브젝트 출연시 프레임을 낮춰서라도 게임 내용에는 지장이 없게끔 렌더링 프레임만 따로 분리해 프레임 스키핑 처리를 하는 경우가 많죠.


여기에 반응성 등을 이유로 렌더링 + 입력 프레임은 동일하게 처리하기도 하고요.


멀티코어 프로그래밍에서는 스레드 분리등을 통한 프레임 제한을 없애는 경우도 존재합니다. (렌더링의 경우는 제한을 두는게 일반적이고, 입력 프레임이나 네트웍 처리 등의 백그라운드 동작을 최대한 프레임 제한없이 처리하려는 경우를 말함)



이렇듯 프레임이란 처리 단위로 명명할 수 있는데요, 초당 몇번 처리할 수 있느냐라고 보시면됩니다.

'C++ > Rendering' 카테고리의 다른 글

cocos2d-x 3.3rc0 설치하기  (0) 2014.12.09
초당 프레임에 대한 썰  (0) 2013.12.10
[리소스] 스프라이트 자료  (0) 2013.11.27
클라이언트 테스트  (0) 2009.12.29
SDL - Simple Directmedia Layer  (0) 2008.09.24
Posted by 엘키 엘키

댓글을 달아 주세요


Sprite Database
http://sdb.drshnaps.com/

Super Sprite
http://erantzo.awardspace.com/

Fenrir's Sprite
http://fenrir.finalfantasyq.com/index.html

Game Sprites
http://www.panelmonkey.net/category.php?id=1

Game Sprite Archives
http://www.gsarchives.net/index2.php

Scroll Boss
http://scrollboss.illmosis.net/mainmenu.php

The People's Sprites
http://www.panelmonkey.net/ 


The Shyguy Kingdom
http://tsgk.captainn.net/ 


nes snes sprites
http://www.nes-snes-sprites.com/ 


The Video Game Museum
http://www.vgmuseum.com/


비디오게임 맵 정보 사이트
http://vgmaps.com/


Video Game Sprites
http://www.videogamesprites.net/


Pixel Art at pixeljoint.com
http://www.pixeljoint.com/default.asp

'C++ > Rendering' 카테고리의 다른 글

cocos2d-x 3.3rc0 설치하기  (0) 2014.12.09
초당 프레임에 대한 썰  (0) 2013.12.10
[리소스] 스프라이트 자료  (0) 2013.11.27
클라이언트 테스트  (0) 2009.12.29
SDL - Simple Directmedia Layer  (0) 2008.09.24
Posted by 엘키 엘키

댓글을 달아 주세요

http://msdn.microsoft.com/en-us/library/aa272889%28v=VS.60%29.aspx


Routine Mappings

Visual Studio 6.0
This topic has not yet been rated

The generic-text routine mappings are defined in TCHAR.H. _tccpy and _tclen map to functions in the MBCS model; they are mapped to macros or inline functions in the SBCS and Unicode models for completeness. For information on a generic text routine, see the help topic about the corresponding SBCS-, _MBCS-, or _UNICODE-related routine.

More specific information about individual routines listed in the left column below is not available in this documentation. However, you can easily look up the information on a corresponding SBCS-, _MBCS-, or _UNICODE-related routine. Use the Search command on the Help menu to look up any generic-text routine listed below.

For related information, see Generic-Text Mappings in TCHAR.H.

Generic-Text Routine Mappings

Generic-Text 
Routine Name
SBCS (_UNICODE & 
MBCS Not Defined)

_MBCS Defined

_UNICODE Defined
_fgettcfgetcfgetcfgetwc
_fgettcharfgetcharfgetchar_fgetwchar
_fgettsfgetsfgetsfgetws
_fputtcfputcfputcfputwc
_fputtcharfputcharfputchar_fputwchar
_fputtsfputsfputsfputws
_ftprintffprintffprintffwprintf
_ftscanffscanffscanffwscanf
_gettcgetcgetcgetwc
_gettchargetchargetchargetwchar
_gettsgetsgetsgetws
_istalnumisalnum_ismbcalnumiswalnum
_istalphaisalpha_ismbcalphaiswalpha
_istascii__isascii__isasciiiswascii
_istcntrliscntrliscntrliswcntrl
_istdigitisdigit_ismbcdigitiswdigit
_istgraphisgraph_ismbcgraphiswgraph
_istleadAlways returns false_ismbbleadAlways returns false
_istleadbyteAlways returns falseisleadbyteAlways returns false
_istlegalAlways returns true_ismbclegalAlways returns true
_istlowerislower_ismbcloweriswlower
_istprintisprint_ismbcprintiswprint
_istpunctispunct_ismbcpunctiswpunct
_istspaceisspace_ismbcspaceiswspace
_istupperisupper_ismbcupperiswupper
_istxdigitisxdigitisxdigitiswxdigit
_itot_itoa_itoa_itow
_ltot_ltoa_ltoa_ltow
_puttcputcputcputwc
_puttcharputcharputcharputwchar
_puttsputsputsputws
_tmainmainmainwmain
_sntprintf_snprintf_snprintf_snwprintf
_stprintfsprintfsprintfswprintf
_stscanfsscanfsscanfswscanf
_taccess_access_access_waccess
_tasctimeasctimeasctime_wasctime
_tccpyMaps to macro or inline function_mbccpyMaps to macro or inline function
_tchdir_chdir_chdir_wchdir
_tclenMaps to macro or inline function_mbclenMaps to macro or inline function
_tchmod_chmod_chmod_wchmod
_tcreat_creat_creat_wcreat
_tcscatstrcat_mbscatwcscat
_tcschrstrchr_mbschrwcschr
_tcsclenstrlen_mbslenwcslen
_tcscmpstrcmp_mbscmpwcscmp
_tcscollstrcoll_mbscollwcscoll
_tcscpystrcpy_mbscpywcscpy
_tcscspnstrcspn_mbscspnwcscspn
_tcsdec_strdec_mbsdec_wcsdec
_tcsdup_strdup_mbsdup_wcsdup
_tcsftimestrftimestrftimewcsftime
_tcsicmp_stricmp_mbsicmp_wcsicmp
_tcsicoll_stricoll_stricoll_wcsicoll
_tcsinc_strinc_mbsinc_wcsinc
_tcslenstrlenstrlenwcslen
_tcslwr_strlwr_mbslwr_wcslwr
_tcsnbcnt_strncnt_mbsnbcnt_wcnscnt
_tcsncatstrncat_mbsnbcatwcsncat
_tcsnccatstrncat_mbsncatwcsncat
_tcsncmpstrncmp_mbsnbcmpwcsncmp
_tcsnccmpstrncmp_mbsncmpwcsncmp
_tcsnccnt_strncnt_mbsnccnt_wcsncnt
_tcsnccpystrncpy_mbsncpywcsncpy
_tcsncicmp_strnicmp_mbsnicmp_wcsnicmp
_tcsncpystrncpy_mbsnbcpywcsncpy
_tcsncset_strnset_mbsnset_wcsnset
_tcsnextc_strnextc_mbsnextc_wcsnextc
_tcsnicmp_strnicmp_mbsnicmp_wcsnicmp
_tcsnicoll_strnicoll_strnicoll_wcsnicoll
_tcsninc_strninc_mbsninc_wcsninc
_tcsnccnt_strncnt_mbsnccnt_wcsncnt
_tcsnset_strnset_mbsnbset_wcsnset
_tcspbrkstrpbrk_mbspbrkwcspbrk
_tcsspnp_strspnp_mbsspnp_wcsspnp
_tcsrchrstrrchr_mbsrchrwcsrchr
_tcsrev_strrev_mbsrev_wcsrev
_tcsset_strset_mbsset_wcsset
_tcsspnstrspn_mbsspnwcsspn
_tcsstrstrstr_mbsstrwcsstr
_tcstodstrtodstrtodwcstod
_tcstokstrtok_mbstokwcstok
_tcstolstrtolstrtolwcstol
_tcstoulstrtoulstrtoulwcstoul
_tcsupr_strupr_mbsupr_wcsupr
_tcsxfrmstrxfrmstrxfrmwcsxfrm
_tctimectimectime_wctime
_texecl_execl_execl_wexecl
_texecle_execle_execle_wexecle
_texeclp_execlp_execlp_wexeclp
_texeclpe_execlpe_execlpe_wexeclpe
_texecv_execv_execv_wexecv
_texecve_execve_execve_wexecve
_texecvp_execvp_execvp_wexecvp
_texecvpe_execvpe_execvpe_wexecvpe
_tfdopen_fdopen_fdopen_wfdopen
_tfindfirst_findfirst_findfirst_wfindfirst
_tfindnext_findnext_findnext_wfindnext
_tfopenfopenfopen_wfopen
_tfreopenfreopenfreopen_wfreopen
_tfsopen_fsopen_fsopen_wfsopen
_tfullpath_fullpath_fullpath_wfullpath
_tgetcwd_getcwd_getcwd_wgetcwd
_tgetenvgetenvgetenv_wgetenv
_tmainmainmainwmain
_tmakepath_makepath_makepath_wmakepath
_tmkdir_mkdir_mkdir_wmkdir
_tmktemp_mktemp_mktemp_wmktemp
_tperrorperrorperror_wperror
_topen_open_open_wopen
_totlowertolower_mbctolowertowlower
_totuppertoupper_mbctouppertowupper
_tpopen_popen_popen_wpopen
_tprintfprintfprintfwprintf
_tremoveremoveremove_wremove
_trenamerenamerename_wrename
_trmdir_rmdir_rmdir_wrmdir
_tsearchenv_searchenv_searchenv_wsearchenv
_tscanfscanfscanfwscanf
_tsetlocalesetlocalesetlocale_wsetlocale
_tsopen_sopen_sopen_wsopen
_tspawnl_spawnl_spawnl_wspawnl
_tspawnle_spawnle_spawnle_wspawnle
_tspawnlp_spawnlp_spawnlp_wspawnlp
_tspawnlpe_spawnlpe_spawnlpe_wspawnlpe
_tspawnv_spawnv_spawnv_wspawnv
_tspawnve_spawnve_spawnve_wspawnve
_tspawnvp_spawnvp_spawnvp_tspawnvp
_tspawnvpe_spawnvpe_spawnvpe_tspawnvpe
_tsplitpath_splitpath_splitpath_wsplitpath
_tstat_stat_stat_wstat
_tstrdate_strdate_strdate_wstrdate
_tstrtime_strtime_strtime_wstrtime
_tsystemsystemsystem_wsystem
_ttempnam_tempnam_tempnam_wtempnam
_ttmpnamtmpnamtmpnam_wtmpnam
_ttoiatoiatoi_wtoi
_ttolatolatol_wtol
_tutime_utime_utime_wutime
_tWinMainWinMainWinMainwWinMain
_ultot_ultoa_ultoa_ultow
_ungettcungetcungetcungetwc
_vftprintfvfprintfvfprintfvfwprintf
_vsntprintf_vsnprintf_vsnprintf_vsnwprintf
_vstprintfvsprintfvsprintfvswprintf
_vtprintfvprintfvprintfvwprintf


Posted by 엘키 엘키

댓글을 달아 주세요

struct CHAR_COLLECTION_DATA
{
	int CharID;
	int Value;
	int ValueCode;
};

CHAR_COLLECTION_DATA CollectionData  = {m_CharID, m_Value, m_ValueCode };

이런 코드가 있었다.



기능을 추가 하시려다보니 습관적으로


struct CHAR_COLLECTION_DATA
{
	int CharID;
	int ClassID; // 다른 변수를 중간에 추가함.
	int Value;
	int ValueCode;
};

CHAR_COLLECTION_DATA CollectionData  = {m_CharID, m_Value, m_ValueCode };


같은 코드고 컴파일 오류도 없지만 원래 코드와 다르게, CharID, Value, ValueCode를 채우지 않고, CharID, ClassID, Value에만 값을 채우는 코드가 되어버렸다.



물론 사용 코드를 전부다 훓어보지 않은 문제가 있긴 하지만, 컴파일 오류로 강제되지 않은 초기화도 좋은 제약은 아니다.


struct CHAR_COLLECTION_DATA
{
	int CharID;
	int ClassID; // 다른 변수를 중간에 추가함.
	int Value;
	int ValueCode;

	CHAR_COLLECTION_DATA()
                : CharID(0)
		, ClassID(0)
		, Value(0)
		, ValueCode(0)
	{

	}


	CHAR_COLLECTION_DATA(int charID, int classID, int value, int valueCode)
		: CharID(charID)
		, ClassID(classID)
		, Value(value)
		, ValueCode(valueCode)
	{

	}

};


기존 코드가 이렇게 짜여져 있었다면, 기존 코드였던


CHAR_COLLECTION_DATA CollectionData(m_CharID, m_Value, m_ValueCode);


는 컴파일 오류를 일으킨다.


자연스레 


CHAR_COLLECTION_DATA CollectionData(m_CharID, m_ClassID, m_Value, m_ValueCode);


위와 같이 고치게 될 것이다.



물론 모든 상황에서 주의 깊게 코드를 찾아보고 고치면 얼마나 좋겠냐 만은, 커버리지는 높을수록 좋은 것.


컴파일 오류로 막을 수 있는 습관은 갖추는 게 좋다.



구조체 이니셜라이저는 자제 하자.

Posted by 엘키 엘키

댓글을 달아 주세요


블로그 이미지
Software Engineer
엘키

공지사항

Yesterday31
Today29
Total1,605,483

달력

 « |  » 2020.8
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31          

글 보관함