글 목록 보기

Atachment
첨부 '3'
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

C++ 템플릿 상속엔 골 때리는 문제가 있는데 ...

바로 베이스클래스의 멤버에 접근하려면 베이스 클래스의 이름을 명시해야 한다는 것이다... 안그러면 이름을 못찾아온다

사람 상당히 귀찮게 만드는놈이라 할 수 있겠다.

보통 일반적으론 볼일이 없고 Mixin 을 이용하거나 아니면 Effective C++ 을 읽으면서 알게된다(책에는 "못찾는다" 라고 되어 있다)


간단히 말하면 이런 코드다

#include <cstdio>

void foo()
{
	printf("Global Function\n");
}
template <typename T>
class Cls1
{
	T Var1;
public:
	void foo()
	{
		printf("Member Function\n");
	}
};

template <typename T>
class Cls2 : public Cls1<T>
{
	T Var2;
public:
	void test()
	{
		Cls1<T>::foo();
	}
};

int main()
{
	Cls2<int> cls2;
	cls2.test();

	return 0;
}


근데 만약 명시 하지 않으면 어떻게 될까?


일단 최신의 VC++ 2012에서 돌려보자

01.png


헐...? 정확히 멤버 함수를 찾아온다. 여기엔 올리지 않겠지만 VS2005~2010 도 모두 같은 동작을 한다.

다른컴파일러에서 해보자. gcc 4.4다.


02.png


헐?! 글로벌 함수를 찾는다 (...) 이거뭥미.


그럼 최신의 C++0x를 지원하는 gcc4.7에서 해보자.


03.png


역시 전역함수를 찾는다.


표준문서는 귀찮아서 (...) 확인하지 않았지만 관련 서적 등을 보면 gcc의 동작이 맞는 것으로 보인다.
하지만 저런 코드를 짜면서 gcc 쪽 동작을 원하는 사람이 과연 있을까... 하는 생각이 든다. 일반적인 클래스를 만드는 느낌으로 당연히 멤버함수가 호출 될 것이라고 생각 하지 않을까? 이 결과를 확인하면서 C++은 당최 생각대로 움직여 주지 않는 매저키스트 들을 위한 언어란 누군가의 말이 귓가에 맴돈다 (...)


결론 : EC++에 나온대로 그냥 제대로 포커스 지정 하자 (...) 야!


PS. gcc 에서는 저렇게 두가지 모두 있는 경우가 아니라 전역 foo 함수가 없는 (즉 이름을 찾을 수 없는) 경우에는 당연히 이름을 찾지 못해 에러를 내는데, 이 경우 컴파일 옵션에 -fpermissive 를 추가 하는 것으로 멤버함수로의 연결이 가능하다(워닝은 뜬다)
단 전역 foo 함수가 존재 할 경우 저 옵션을 그냥 무시하고 그냥 전역 함수로 연결해 버린다.


PS2. 혹시 LLVM-clang 을 사용할 수 있는 환경에 계신분은 어떤 결과가 나오는지 알려주시면 좋겠다.



?
  • ?
    123 2012.09.02 19:18
    VS 에서는 자동으로 찾아주네요.. 역시 상용이라 틀린가보네요..
    clang 으로 컴파일 해서 실행해보니 gcc 하고 같네요. .
    관련글에는 이렇게 나오네요
    While non-dependent names are resolved "normally" – when the template is defined,
    the resolution for dependent names happens at the point of the template’s instantiation.
    그러까 템플릿 인스턴스시 resolve 가 되게할려면 dependent name 으로 만들어 줘야 되네요
    Cls1<T>::foo() or this->foo() 이런식으로..

    http://eli.thegreenplace.net/2012/02/06/dependent-name-lookup-for-c-templates/

2012.08.17 02:06

[윈도8] 윈도8 구경1

Lyn
조회 수 26187 추천 수 0 댓글 1
Atachment
첨부 '2'
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

얼마전 MSDN 에 정식으로 올라온 윈도8 입니다.
Enterprise 버전은 라이센스가 없어서 Pro로 설치 했네요


Untitled.png


슬슬 제대로 둘러봐야 겠지만 첫인상 아주 좋습니다.
빠릿빠릿해요 그냥


아직 호환성이 걱정되는 놈들이 있어 Win7하고 듀얼부팅을 세팅 해 뒀는데... OS 선택 메뉴가 아주 화려하네요.


dual boot.png

?
  • ?
    사무엘 2012.09.11 18:52
    윈8.. 윈도우 XP 이래로 트렌드이던 둥근 모서리가 없어지고,
    제목이 창 제목의 왼쪽이 아니라 가운데에 찍히는 디자인이 윈도우 3.x 이래로 다시 부활했고,
    그러데이션이 그냥 단색(solid color)로 바뀌는 등..
    모바일을 의식해서 그런지 디자인이 좀 더 검소해지고 단순해졌지요. 단순히 변화만을 위한 변화인 것도 느껴지더군요.

    일부 너무 급격한 변화는 왜 이런 걸 만들었는지 의문이 드는 것도 있습니다.
    참, MS 오피스는 2007 이래로 진작부터 제목이 가운데에 찍히는 스타일로 회귀했지요. ^^

Lyn
조회 수 25543 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
void foo1(string str = "DefaultString")
{
//값으로넘기기
}
 
void foo2(const string str = "DefaultString")
{
//const 값으로넘기기
}
 
void foo3(string& str = "DefaultString")
{
//이건 에러남...
}
 
void foo4(const string& str = "DefaultString")
{
//const 레퍼런스로 넘기기
}
 
void foo5(string& name = string("DefaultString"))
{
//임시객체 넘기기
}
 
void foo6(const string& name = string("DefaultString"))
{
//const 임시객체 넘기기
}
 
static std::string DEFAULT_STRING = "DefaultString";
void foo7(string& str = DEFAULT_STRING)
{
//이건 DEFAULT_STRING이 바뀔 가능성이 있음.. 위험한코드
}
 
const static std::string CONST_DEFAULT_STRING = "DefaultString";
void foo8(const string& str = CONST_DEFAULT_STRING)
{
//static const 레퍼런스 객체 넘기기 (boost가 자주 쓴 방식... string은 아니지만)
}
?

Lyn
조회 수 27336 추천 수 0 댓글 2
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

Devpia에 자꾸 질문이 올라와서 정리 해 둔다 ...


1. 32bit 프로그램에서는 64bit DLL을 사용할 수 없다. 반대도 마찬가지


2. 32bit 프로그램에서는 64bit ActiveX를 사용할 수 없다. 역시 반대도 마찬가지.


3. 64bit OS에서 32bit 프로그램이 Windows\System32에 접근하면 Windows\SysWOW64로 리다이렉트 된다. 


4. 32bit 프로그램에서는 64bit 프로세스의 정보를 얻어올 수 없다.


5. 64bit OS에서는 32bit 로 된 ShellExtension 을 띄울 수 없다. 단 32bit 프로그램이 ShellAPI로 ShellExtension 을 띄우려면 32bit용 ShellExtinsion 이 설치되어 있어야 한다(간단히 말해서 32/64 둘다만들란 소리다!)


6. ODBC는 32bit 와 64bit를 따로 등록해야 한다(64bit 의 제어판에 있는건 64bit 용 ODBC다. 32bit용은 SysWOW64에 가서 실행해야 한다)

한쪽만 등록할 경우 bit가 다르면 안보인다.


7. 윈도우 서비스는 공통이다. 신경 안써도 됨

?
  • ?
    ssonacy 2012.07.20 16:31

    64bit  프로세스는 32bit DLL 를 로드 할수 없다구요 ?

    흠 ...??

  • profile
    Lyn 2012.07.21 13:00

    네 없습니당


Lyn
조회 수 26624 추천 수 0 댓글 0
Atachment
첨부 '1'
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
#include <windows.h>
#include <cstdio>
#include <cstdlib>

bool isThreadWaiting(HANDLE ThreadHandle)
{
	bool Result = false;

	SuspendThread(ThreadHandle);
	CONTEXT ThreadContext;
	ThreadContext.ContextFlags = CONTEXT_CONTROL;
	BOOL a = GetThreadContext(ThreadHandle, &ThreadContext);
	INT_PTR* StackPointer = reinterpret_cast<INT_PTR*>(ThreadContext.Esp);

	HMODULE DLLHandle = LoadLibraryA("Ntdll.dll");
	INT_PTR WaitFunctionPtr = reinterpret_cast<INT_PTR>(GetProcAddress(DLLHandle, "NtWaitForSingleObject")); 
	//WaitForSingleObject의 종착점이 되는 함수가 NtWaitForSingleObject
	
	if ((*StackPointer >= WaitFunctionPtr) && (*StackPointer <= WaitFunctionPtr + 50))
	{
		//대충 +50을 해 주는 이유는 실제 복귀주소로 저장된 곳이 NtWaitForSingleObject의 시작주소가 아니라 조금 실행된 뒤이기 때문
		Result = true;		
	}

	FreeLibrary(DLLHandle);
	ResumeThread(ThreadHandle);

	return Result;
}

DWORD PASCAL ThreadFun1(PVOID Param)
{
	WaitForSingleObject(HANDLE(Param), INFINITE);

	return 0;
}

DWORD PASCAL ThreadFun2(PVOID Param)
{
	while(true)
	{
		Sleep(100000);
	}

	return 0;
}
void main()
{	
	HANDLE Event = CreateEvent(nullptr, TRUE, FALSE, nullptr);

	HANDLE Thread1 = CreateThread(nullptr, 0, &ThreadFun1, reinterpret_cast<LPDWORD>(Event), 0, nullptr);
	HANDLE Thread2 = CreateThread(nullptr, 0, &ThreadFun2, nullptr, 0, nullptr);

	Sleep(1000); //Thread 돌 시간좀 주고 ...

	printf("Is Thread1 Waiting? %s\n", isThreadWaiting(Thread1) ? "Yes" : "No");
	printf("Is Thread2 Waiting? %s\n", isThreadWaiting(Thread2) ? "Yes" : "No");

	system("pause");
}


sc1.png


Wait계열 함수가 몇종류 더 있는데 그것도 그냥 각자 처리해 주면 간단...


?

Lyn
조회 수 24192 추천 수 0 댓글 0
Atachment
첨부 '1'
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
<작성중>
소스는 첨부파일에. 
#include <cstdio>
#include <windows.h>
#include "Coroutine.h"
 
class NumberCount : public Coroutine<int>
{
protected:
	void Execute() override
	{
		for (int i = 0; i < 100; ++i)
		{			
			yield_return(i);
		}
	}
};
 
class NumberPrint : public Coroutine<void>
{
protected:
	void Execute() override
	{
		for (int i = 0; i < 100; ++i)
		{		
			printf("NumberPrint : %d\n", i);
			yield;
		}
	}
};
 
void wmain()
{	
	ConvertThreadToFiber((LPVOID)GetCurrentThreadId());
	
	NumberCount Co1;
	NumberPrint Co2;
 
	for (int i = 0; i < 100; ++i)
	{
		printf("NumberCount : %d\n", Co1.Resume());
		Co2.Resume();
		Sleep(1000);
	}	
}
 

?

Lyn
조회 수 24704 추천 수 0 댓글 0
Atachment
첨부 '1'
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

1. v8 빌드


2. 사용법



?

2012.02.19 23:15

[작성중] 알려진 포트

Lyn
조회 수 24230 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

TCP


21 : Ftp

22 : SSH

80 : Http

443 : Https

3389 : RDP (Windows 원격 데스크탑)


?

Lyn
조회 수 30813 추천 수 0 댓글 4
Atachment
첨부 '1'
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

C++의 STL 에서는 여러가지 알고리즘을 제공한다.
그중 "임의의" 동작을 할 수 있는 알고리즘들은 그 "동작" 의 대상이 되는 인자를 받도록 되어 있는데, 
그 "동작"의 조건은 ()연산자로 호출이 가능할것! 이다.


그 동작을 만족시키는것은 C에서는 함수가 있다.
또 C++에서는 STL 과 함께 소개된 함수객체(Functor)가 있으며, STL 초기부터 제공된 bind1st, bind2nd가 있고, boost에서 제공되는 mem_fn 도 있으며, 이 모든것을 통합한 범용 bind(C++11 or boost에 포함)도 존재한다.

그리고 최신의 C++11 표준에 포함된 lambda도 있고, boost의 lambda도 있지만, 이쪽은 C++11 표준에 lambda가 포함 된 이상 더이상 쓸 일은 없을테니 이번 실험에선 제외한다.


실험순서는 전역함수, bind된 전역함수, 함수객체, 람다, bind된 람다, auto를 이용해 bind된 람다 의 순이다.

실험은 Visual C++ 2010 Sp1, x86 Debug Build에서 테스트 하엿다. Release Mode 도 특성은 동일하다.

궂이 Debug Build로 테스트 한 이유는 Release모드에서 자꾸 전역함수를 inline화 시키는 바람에 =_=;


코드 나간다.


#include <cstdlib>
#include <cstdio>
#include <vector>
#include <random>
#include <cstdint>
#include <algorithm>
#include <functional>
#include <windows.h>
 
using namespace std;
 
__int64 g_NumberSum;
 
void GetSumFunction(int Num)
{
	g_NumberSum = g_NumberSum + Num;
}
 
struct GetSumFunctor
{
	void operator()(int Num)
	{
		g_NumberSum = g_NumberSum + Num;
	}
};
 
void wmain()
{
	const int NUMBER_COUNT = 100000000;
 
	mt19937_64 RandomEngine;
	uniform_int <> RandomRange(0, INT32_MAX);
	RandomEngine.seed(GetTickCount());
 
	vector<int> RandumNumbers;
	RandumNumbers.reserve(NUMBER_COUNT);
	for (int i = 0; i < NUMBER_COUNT; ++i)
	{
		RandumNumbers.push_back(RandomRange(RandomEngine));
	}
 
	DWORD Tick;
//function
	g_NumberSum = 0;
	Tick = GetTickCount();
	for_each(RandumNumbers.begin(), RandumNumbers.end(), GetSumFunction);
	printf("Global Function :: Sum : %I64d, Time : %dms\n", g_NumberSum, GetTickCount() - Tick);
//bind function
	g_NumberSum = 0;
	function<void(int)> FunctionObject = bind(&GetSumFunction, tr1::placeholders::_1);
	Tick = GetTickCount();
	for_each(RandumNumbers.begin(), RandumNumbers.end(), FunctionObject);
	printf("Bind Function   :: Sum : %I64d, Time : %dms\n", g_NumberSum, GetTickCount() - Tick);
//functor
	g_NumberSum = 0;
	Tick = GetTickCount();	
	for_each(RandumNumbers.begin(), RandumNumbers.end(), GetSumFunctor());
	printf("Functor         :: Sum : %I64d, Time : %dms\n", g_NumberSum, GetTickCount() - Tick);
//C++ 11 Lambda
	g_NumberSum = 0;
	Tick = GetTickCount();
	for_each(RandumNumbers.begin(), RandumNumbers.end(), 
		[](int Num)
		{
			g_NumberSum = g_NumberSum + Num;
		});
	printf("C++11 Lambda    :: Sum : %I64d, Time : %dms\n", g_NumberSum, GetTickCount() - Tick);
//C++11 Bind Lambda
	g_NumberSum = 0;
	Tick = GetTickCount();
	function<void(int)> BindLambda = 
		[](int Num)
		{
			g_NumberSum = g_NumberSum + Num;
		};
	for_each(RandumNumbers.begin(), RandumNumbers.end(), BindLambda);
	printf("Bind Lambda     :: Sum : %I64d, Time : %dms\n", g_NumberSum, GetTickCount() - Tick);
//C++11 Auto bind Lambda
	g_NumberSum = 0;
	Tick = GetTickCount();
	auto AutoBindLambda = 
		[](int Num)
		{
			g_NumberSum = g_NumberSum + Num;
		};
	for_each(RandumNumbers.begin(), RandumNumbers.end(), AutoBindLambda);
	printf("Auto Bind Lambda:: Sum : %I64d, Time : %dms\n", g_NumberSum, GetTickCount() - Tick); 
} 



아래는 결과이다.

lambda.png


결과를 보면 lambda 가 가장 빠른 것을 볼 수 있다. 길게 나불대지 않고 성능 이슈와 원인을 아래 간략히 적어본다.
1. 전역함수의 경우 함수 Call 오버헤드에 의해 속도가 조금 감소하엿다.

2. lambda, functor 는 사실상 오차범위 내의 차이라고 보인다.

3. bind lambda 의 경우는 std::fuction 객체가 함수호출 정보를 RTTI에 의존하는 특징때문에 속도를 왕창 까먹게 된다.

4. bind 된 전역함수의 경우는 RTTI의 오버헤드 + 함수호출로 인해 가장 느려진다.

5. auto를 사용해 변수에 저장한 lambda 는 std::fuction객체에 저장 하는 것이 아니라 일종의 inline 함수처럼 구현해준다. 그래서 오버헤드가 전혀 없이 빠른 속도를 보여준다. 즉 같은 함수객체를 2번이상 이용 할 경우 코드를 Copy&Paste 하지 않아도 auto를 이용하면 성능과 중복방지 두마리 코드를 다 잡을 수 있다.

?
  • ?
    elrha 2012.08.16 09:57

    으아 이거 좋은정보네요


    테스트는 안해봤지만 auto 객체 마우스 오버해보면 std::function으로 나올듯 한데..


    결국 컴파일러 지능테스트인건가요 ㅋㅋㅋㅋ

  • profile
    Lyn 2012.08.16 22:53

    아뇨 함수포인터 취급해요 ㅎㅎ


    컴파일 타임에 완전한 호출 정보를 알고있는 상황에서 궂이 오버헤드가 있는 std::function으로 컴파일할 이유가 없죠

  • ?
    11ho 2014.03.24 20:52
    감사합니다. 속이 다 후련하네요 ㅠㅠ
  • ?
    해피 2015.07.17 10:15
    퍼가용

2012.01.13 16:10

Boost 빌드 방법

Lyn
조회 수 30853 추천 수 0 댓글 1
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
1. Gem 만들기
bootstrap 실행 -> b2 실행파일이 생성

1.48.0에선 bjam -> b2 로 바뀌었다. 근데 bjam 도 그대로 된다 (...) 같은걸 2개 만들어줌

2. b2 빌드옵션
toolset=<>            ▷ 컴파일러 설정
--buildtype=<>      ▷ 빌드방법 설정
--libdir=<>            ▷ output 폴더 설정
--architecture=<>   ▷ target platform 설정
address-model=<>  ▷ bit수 설정
install                    ▷ 빌드방법 설정
define=<>              ▷ define 상수 설정
-j<>                      ▷ 병렬컴파일할 코어갯수 설정

절대로 = 앞뒤에 공백 넣지 말것. 반드시 원하는 컴파일러/bit수의 Command Prompt  에서 실행할것

3. 예제
vc++ 2010으로 모든형태의 라이브러리(debug dll, debug static, release dll, release static)를 CRT 버전을 최신으로 하여 특정 Path에  쿼드코어로 빌드 할경우

AMD64(EM64T)는 x86 아키텍쳐에 address 를 64bit로 지정해야한다. x64, AMD64, EM64T 등의 키워드는 불가능

  1. 32bit build

    b2 -j4 toolset=msvc-10.0 --build-type=complete define=_BIND_TO_CURRENT_VCLIBS_VERSION  --libdir=c:\library\boost\lib\i386 install

  2. 64bit build
    b2 -j4 toolset=msvc-10.0 --build-type=complete  define=_BIND_TO_CURRENT_VCLIBS_VERSION --libdir=c:\library\boost\lib\amd64 architecture=x86 address-model=64 install
?
  • profile
    Lyn 2012.01.13 16:11

    실수로 글을 지워서 다시썻다 씁 ㅡㅡ;


Board Pagination Prev 1 ... 4 5 6 7 8 9 10 11 12 13 Next
/ 13