'D Programming'에 해당되는 글 3건

  1. D언어에서의 함수 포인터 2011/06/25
  2. 변수에 void를 대입하는 문장의 의미. 2011/06/22
  3. Visual D (2) 2010/10/07
D1에서는 아래와 같은 C스타일 함수포인터 선언이 가능했다.
typedef int (*functionName) (int a, int b);


D2부터는 C스타일의 함수 포인터 선언이 불가능해지고 D스타일 함수 포인터만을 사용해야 한다. (D2에서 typedef가 폐기된 영향으로 추측된다) 선언 형식은 다음과 같다.

alias [반환형] function ([매개변수 목록]) [이름];

대리자 포인터의 경우 function 대신 delegate를 사용하면 된다. 선언한 함수 포인터 변수에는 일반적인 함수의 주소, 또는 함수 리터럴을 대입할 수 있다. 함수 포인터 변수에 대리자 리터럴을 담을 수는 없다.

 
alias int function(string b) func;

int foo(string b)
{
	writeln(b);
	
	return 0;
}

void main()
{
	func f;
	
	f = &foo;
	
	f("hello D!");
	
	f = function(string b)
	{
		writeln(b);
		return 1;
	};
	
	f("hello D!");
}

저작자 표시 비영리 변경 금지
D의 모든 내장 형식은 .init 속성에 기본값을 가지고 있으며 변수가 선언되면 메모리가 기본값으로 초기화된다. 이는 변수를 초기화하지 않고 사용하더라도 런타임에 문제가 발생하지 않도록 돕는 장치이다. 다음 코드를 보자. (표준 라이브러리를 사용하기 위한 import선언은 배제한다.)

void main()
{
   int a;
   writeln(a);
}

위 코드에서는 a가 int.init, 즉 0 으로 초기화되어 0이 출력된다. 그렇다면 a에 void를 대입하면 어떻게 될까.

void main()
{
   int a = void;
   writeln(a);
}

위 코드의 실행 결과 a는 쓰레기 값이 된다. 변수의 자동 초기화는 초기화되지 않은 변수가 부주의하게 사용되는 경우를 대비한 D의 배려이므로, 만약 변수가 생성당시 초기화되지 않았더라도 사용되기 전에 어떤 값으로 초기화되는 것이 보장되는 경우에는 불필요한 오버헤드가 된다. 이 때 변수에 void를 대입함으로서 자동 초기화 기능을 변수 생성 과정에서 배제할 수 있다. 이 기능은 단일한 내장 형식 뿐 아니라 배열, 구조체에도 동일하게 적용된다.

//배열의 경우
int[3] getarray()
{
	int[3] array = void;
	
	foreach(i, ref a; array)
		a = i;
	
	return array;
}

//구조체의 경우
struct S { int a; bool b; }

void getByRef(ref S s)
{
	s.a = 123;
	s.b = true;
}

void main()
{
	S s = void;
	getByRef(s);
	writeln(s.a, s.b);
}

저작자 표시 비영리 변경 금지

Visual D

from 노트/Programming D 2010/10/07 14:13

Visual Studio에 D를 통합시키는 플러그인. 문서 작성 현재 0.3버전이며 지속적으로 업데이트되고 있는 몇 안되는 D용 IDE이다. 다른 하나는 D-IDE이며 .NET 4.0기반의 독자적인 IDE환경을 구축하고 있다. 이쪽도 사용하려면 못할 것은 없지만 일단 윈도우 개발자에게 VS보다 익숙한 환경은 없으므로 VisualD가 최근 선호되는 경향이다. (대표적인 멀티미디어 API 바인딩인 Derelict도 VisualD용 프로젝트 파일을 제공하고 있다)

 

다만 개발환경을 구축하는 작업이 꽤 불편한데, 틈틈이 정보를 수집해서 외부 라이브러리를 바인딩하는데 성공하기까지도 상당한 시간이 소요되었다. 알아낸 바, D 개발환경 구축에는 다음과 같은 준비물이 필요하다.

Visual Studio 2008,2010

DMD

VisualD

유감스럽게도 언어의 확장은 Visual Studio에서만 지원하는 것이기 때문에 MS가 제공하는 각 대표적 언어별 Express버전에서는 Visual D를 사용할 수 없다.

위 순서대로 준비물들을 설치한다. 특히 DMD는 경로작성의 편의성을 위해 드라이브 루트에 근접한 디렉토리에 설치하는 것이 현명하다.

최종적으로 Visual D를 설치한 후 환경설정에 들어간다.

 

도구-옵션-프로젝트 및 솔루션 트리를 열어보면 Visual D Settings가 보인다. VisualD 설치 당시 정확한 DMD의 경로를 제공했다면 대부분의 설정은 되어있을 것이다.

Import paths는 C의 인클루드 디렉토리와 같다. Library paths는 이름 그대로이다. 나머지 것들은 건드릴 필요가 없다.

 

이걸로 설정이 끝날 수 있다면 좋겠지만, 아직 문제가 몇 가지 남아있다.

관련 프로젝트들의 포럼에 따르면 현재 DMD 컴파일러가 IDE가 제공하는 컴파일 메니페스트에서 import path 및 library path를 DMD기본 설정 파일인 sc.ini의 설정으로 덮어써버리는 듯 하다.

그래서 프로젝트에 필요한 경로들을 IDE에서 지정해도 해당 모듈을 찾을 수 없다거나 링크할 심볼을 찾을 수 없다거나 하는 메시지만 뜨게 될 것이다.

 

VIsualD 개발자는 (DMD설치경로)/windows/bin/sc.ini에 기록된 기본 스위치에 설정을 추가할 것을 권한다.

 

LIB="%@P%\..\lib";\dm\lib;%DMD_LIB% <- 링크시 라이브러리를 찾을 경로에 VisualD가 제공하는 경로를 추가한다.

DFLAGS="-I%@P%\..\..\src\phobos" "-I%@P%\..\..\src\druntime\import" -ID:\SDK\Derelict2\import <-IDE가 어찌할 수 없으므로 import 경로를 직접 추가할 것.

 

이제 IDE에서 필요한 lib파일을 추가해 줄 수 있는데, C와는 달리 lib파일을 세미콜론이 아닌 공백으로 구분한다. 이점은 상당히 중요하다. 이에 대한 정보를 찾지 못해 오래 헤맸다.

필요한 라이브러리를 추가해주고 빌드하면 성공하는 모습을 볼 수 있다.

--

정정. 문제는 DMD가 아니라 DigitalMars가 제공하는 링커인 OPTLINK에 있는 것으로 보인다. 여전히 도구-프로젝트 및 솔루션-Visual D Settings에 설정된 Import Path는 인식하지 못하지만 각 프로젝트별로 설정되는 Additional Imports의 경로는 문제없이 인식한다. (Visual D 개발자의 의도인지는 불분명)

그러나 라이브러리 경로는 프로젝트에 설정하더라도 여전히 링커에 전달되지 않으므로 sc.ini에 환경변수 DMD_LIB를 유지해야 한다.




참고로 Additional Imports에 주어지는 경로 역시 공백으로 구분된다. 디렉토리 경로에 공백이 들어갈 경우 위와 같이 경로를 큰따옴표로 감싸 주자.




--


여담 :

과거에 국내에서 동일한 이름의 프로젝트를 진행하시던 분이 있었다. D 1.x를 대상으로 하는 IDE였고 한번 돌려본 기억만 나는데 문득 생각나서 찾아보니 프로젝트가 폐기 된 것 같다. 이 링크는 유일하게 남아있는 기록.

저작자 표시 비영리 변경 금지