아래 코드는 "C++기초 플러스5판(성안당)"에 있는 프로그래밍 연습문제를 풀다가 작성한 코드입니다.

template <typename T>
T maxn( const T list[], int n);

template<>char* maxn<char*>(const char * list[], int n);


위코드를 컴파일 하면
"템플릿 선언과 매칭되는 것이 없다"는 내용의 에러가 납니다..
왜 그럴까요?

저는 구글링을 하면서 답을 구했는데요.. 잘 생각해 보세요^^
아시는 분들은 댓글 남겨 주세요~~
저작자 표시
신고
by danguria 2011.04.02 09:59

대뜸 질문입니다...
다음 코드에서 문제가 되는 부분을 설명 해 보세요^^

#include <iostream>
using namespace std;
double refcube(const double &ra)
{
 return ra * ra * ra;
}
void swapr(int &a, int &b)
{
 int temp;
 temp = 1;
 a = b;
 b = temp;
}
 
int main()
{
 double side = 3.0;
 long edge = 5L;
 double c1 = refcube(edge);
 double c2 = refcube(7.0);
 double c3 = refcube(side + 10.0);

 long a = 3L;
 long b = 5L;
 swapr(a, b);
 return 0;
}


C++ 기초 플러스 5판(성안당) 438페이지에 답이 있습니다^^

저작자 표시
신고
by danguria 2011.03.30 20:45
거의 2년만에 강석민 강사님의 강의를 다시 듣게 되었습니다.
역시 설명을 참 잘하신다는 느낌을 받았습니다~

그럼... 갈길이 멀기 때문에 바로 정리작업을 들어가겠습니다.(이미 내머리속에 지우개가 발동하고 있습니다..ㅠ)

첫번째 시간에는 객체지향 디자인을 하기 전에 기본적인 c++의 문법을 배웠습니다.

Up casting : "부모 포인터(참조)로 자식객체의 주소를 담을 수 있다" 라는 개념입니다.
장점1. 동종(동일부모의 자식)을 저장하는 collection을 만들 수 있다.
장점2. 동종을 처리하는 함수를 만들 수 있다.

즉, 자식 클래스가 무엇인지 몰라도 동일한 일을 하기 위해서 부모클래스를 가지고 일을 할 수 있다는 말입니다.
나중에 다형성개념이 있을 수 있는 것이  Upcasting이 가능하기 때문인것입니다. (곧, 다형성이 나오니 걱정마세요..)


#include 
using namespace std;

class Animal
{
public:	void Cry() {}
			 int age;
};
class Dog : public Animal
{};
class Cat : public Animal
{};
void NewYear( Dog* p )
{
	++(p->age);
}
int main()
{
	Dog* woori[100];
	
	Animal a; foo(&a);
	Dog d;    foo(&d);  // ok...
}
 
 
NewYear에서는 Dog의 객체를 받기를 기대 하시만, Dog의 부모인 Animal이 와도 된다는 의미 입니다.
((__
저작자 표시
신고
by danguria 2010.06.01 20:40

우리가 보통 포인터를 사용할때는 두가지가 관계가 있다.

하나는, 포인터 자신이고, 다른 하나는 포인팅 되는 오브젝트 이다.

그럼 포인터에 const키워드를 붙이면 어느 것이 상수화 될까?


답은 const키

워드를 붙이는 위치에 따라서 결정되는 것이다.

기준은 * 이다.

*앞에 const키워드를 붙이면(prefixing) 포인팅 되는 오브젝트가 상수화 되는 것이고,

* 뒤에 const키워드를 붙이면(postfixing) 포인터가 상수화 되는 것이다.


예를 들어보도록 한다.

void f1(char* p){
char s[] = "Gorm";

const char* pc = s;                     //pointer to constant
pc[3] = 'g';                                  // error: pc points to constant
pc = p;                                        //ok

char *const cp = s;                  // constant pointer
cp[3] = 'a';                                //ok
cp = p;                                      //error: cp is constant

const char *const cpc = s;      // const pointer to const
cpc[3] = 'a';                              //error: cpc points to constant
cpc = p;                                    //error: cpc is constant
}

코드를 잘 보면 이해가 갈 것이다.

그렇다면 문제!! 아래의 코드를 어떻게 되겠는가?

char *const cp;
char const* pc;
const char* pc2;

이미 답은 제시 했지만.... 첫번째 줄의 코드와 두번째 줄의 코드를 구분 할 수 있는가 하는 문제이다.

포인터를 상수화 할지, 포인팅되는 오브젝트를 상수화 할지는 *를 기준으로 const의 위치에 의해 결정된다과 

했으므로, 두번째 줄의 코드는 상수를 가르키는 포인터이다.




다음의 코드는 컴파일 타임에 에러가 난다. 

에러가 나는 원인이 무엇인지 한번 찾아 보라

void f4(){
int a = 1;
const int c = 2;
const int* p1 = &c;
const int* p2 = &a;
int* p3 = &c;
*p3 = 7;
}


답은 댓글로 달아 주는 센스~~



[참고 자료 : The C++ programming language 3rd, BJARNE STROUSTRUP ]



신고
by danguria 2010.01.03 15:28
오늘 과제를 열심히 하다가 다른 소스에서는 잘 되는데 내가 만든 소스에서는 계속 컴파일 에러가 나는 구문이 있었습니다.

void function( char *path )
{
static char *full = path;
}

어떤 함수에 스태틱 캐릭터 포인터가 있고 함수의 인자로 오는 캐릭터 포인저의 값을 저장하는 구문인데요..

"initializer is not a constant"

위와 같은 에러 메시지가 뜨더군요.. 에러문을 해석하면 스태틱 포인터에 초기화될때 들어가는 값이 상수가 아니라서 안된

다..이런 의미인데 이런 문법적 제약이 있는것은 아닌것으로 알고 있는데다가 다른 소스에서는 컴파일이 잘되니 도무지 알 수
없는 노릇이라 인터넷을 뒤저 보았습니다. 다른 사람들도 저와 같은 현상이 일어나는 것을 알고 있었는데,

static char *full = path;
위의 코드를 아래와 같이 수정하면 되는 것입니다.
static char *full = path;
full = path;
어처구니가 없었습니다.

곰곰히 생각해 본결과, 다른 원인은 모르겠고 컴파일이 잘 되는 소스는 cpp파일이었고, 컴파일에러를 출력하는 소스는 c파일

이었습니다.

이상한 C컴파일러입니다....






혹시 다른 이유를 아시는 분 알려 주세요^^


신고
by danguria 2009.01.13 20:26

Naked Function

 원본 :  http://danguria.springnote.com/pages/2407072

 작성자 : danguria

 이 글을  마음껏 이용하시되 출처를 꼭 밝혀 주세요

 

 

요즘 루트킷 관련 과제를 하다보니 C코드를 많이 보고 있습니다.. 대부분 커널모드에서 동작하는 코드들인데

IDT후킹관련 코드를 보는데 "__declspec(naked) Function()" 이런식의 함수가 보이는 것입니다.

분명히 이건 표준C에내용은 아닌것 같은데.. 뭐지.. 하면서 그냥 지나 치다가 우연히 "Windows 구조와 원리 그리고 Codes"라는 책에서

그 설명을 볼 수 가 있었습니다.

 

결론 부터 간단히 말하자면!!

위와 같은(__declspec(naked)) prefix를 붙이게 되면, 컴파일러가 스택 프레임코드를 생성 시켜 주지 않는다는 것입니다.

스택 프레임은 함수의 파라미터를 편하게 접근하기 위해서 ebp레지스터를 통해 접근하는 방법입니다.

(자세한것은 [어셈블러] 어셈블러로 함수의 호출 원리를 알아보자!! 2탄 을 참고 하세요^^)

시스템 프로그래머에 있어서 어떤 경우에는(특히 후킹에 경우) 스택프레임과 관련된 코드를 자신의 입맛에 맞게 작성해야 할경우 이런 naked함수가 필요 하겠죠.

이름에서도 알수 있듯이 함수의 기본틀을 벗겨서 아무것도 없는 함수를 제공하는 격이 되네요^^

 

다음의 코드는 naked 형식에 의한 함수가 구성된 예입니다.

  1. /*
  2. * Windows 구조와 원리 그리고 Codes책에 있는 예제를 가져 왔습니다.
  3. */
  4. __declspec(naked) NakedFunc()
  5. {
  6. int i;
  7. int j;
  8. _asm  //prolog
  9. {
  10. push ebp
  11. mov ebp, esp
  12. sub esp, _LOCAL_SIZE
  13. }
  14. i = 1;
  15. j = 2;
  16. // Function Body

    _asm   //epilog

  17. {
  18.  mov esp, ebp

    pop ebp

  19. ret
  20. }
  21. }

 

위의 코드에서 어셈코드가 들어간 부분이 스택프레임인데 prolog와 epilog부분이 디폴트로 함수선언시 들어가지만 naked 함수는 이 두부분이 없어진다는 뜻입니다.

 

 

 

 

 

 

 

 

 

 


신고
by danguria 2008.12.30 20:30

요새 C언어로 코드를 짜다 보니까 자잘자잘한 컴파일러 옵션이나 문법을 알게 된다.

전에는 몰랐던 구조체의 메모리 할당에 대해서 잘 알게 되었다.

컴파일러가 구조체의 메모리를 할당할때 가장 큰 타입의 메모리 곱하기 변수 개수를 한다는 것이다.

struct AAA
{
     int a;
     char b[2];
     int c;
};

이렇게 하면 할당되는 메모리는 10byte일 것같지만 실제로 12byte가 된다. 속도를 좀더 올리려는 목적에서 그런다고 한다. 그리고 남는 2byte는 b의 뒤에 빈공간이 있다.

하지만 특별한 상황에는 실제 메모리를 정확하게 잡아야 할때가 있기 때문에
#pragma pack( ... )으로 해결 할 수 있다.

#pragma pack( push )
#pragma pack( 1 )
// 구조체 선언..
#pragma pack( pop )
이런식으로 하면 된다..ㅋ

신고
by danguria 2008.08.01 15:02
| 1 |

티스토리 툴바