이럴수가 asdf 마구 치다가 우연히 찾은 명령어다.

아직 자세하게 뭔지는 모르기에 man page 가져다 붙여두고

좀 봐야겠다. 


SADF(1)                       Linux User's Manual                      SADF(1)


NAME

       sadf - Display data collected by sar in multiple formats.


SYNOPSIS

       sadf [ -d | -D | -H | -p | -x ] [ -t ] [ -V ] [ -P { cpu | ALL } ] [ -s

       [ hh:mm:ss ] ] [ -e [ hh:mm:ss ] ] [ -- sar_options...  ] [ interval  [

       count ] ] [ datafile ]


DESCRIPTION

       The sadf command is used for displaying the contents of data files cre-

       ated by the sar(1) command. But unlike sar, sadf can write its data  in

       many  different  formats.  The default format is one that can easily be

       handled by pattern processing commands like awk (see option -p).


       The sadf command extracts and writes to standard output  records  saved

       in  the datafile file. This file must have been created by a version of

       sar which is compatible with that of sadf.   If  datafile  is  omitted,

       sadf uses the standard system activity file, the /var/log/sa/sadd file,

       where the dd parameter indicates the current day.


       The interval and count parameters are used to tell sadf to select count

       records  at  interval  second  intervals. If the count parameter is not

       set, then all the records saved in the data file will be displayed.


       All the activity flags of sar may be entered on  the  command  line  to

       indicate  which  activities are to be reported. Before specifying them,

       put a pair of dashes (--) on the command line in order not  to  confuse

       the  flags  with  those of sadf.  Not specifying any flags selects only

       CPU activity.



실행 결과

------------------------------------------


$ sadf
TEST    604 1343229001  all %user   0.50
TEST    604 1343229001  all %nice   0.00
TEST    604 1343229001  all %system 1.75
TEST    604 1343229001  all %iowait 0.01
TEST    604 1343229001  all %steal  0.00
TEST    604 1343229001  all %idle   97.74
TEST    604 1343229601  all %user   0.46
TEST    604 1343229601  all %nice   0.04
TEST    604 1343229601  all %system 1.72
TEST    604 1343229601  all %iowait 0.00
TEST    604 1343229601  all %steal  0.00
TEST    604 1343229601  all %idle   97.77
TEST    603 1343230201  all %user   0.48
TEST    603 1343230201  all %nice   0.00
TEST    603 1343230201  all %system 1.74
TEST    603 1343230201  all %iowait 0.00
TEST    603 1343230201  all %steal  0.00
TEST    603 1343230201  all %idle   97.79
TEST    604 1343230801  all %user   0.47
TEST    604 1343230801  all %nice   0.00
TEST    604 1343230801  all %system 1.72
TEST    604 1343230801  all %iowait 0.00
TEST    604 1343230801  all %steal  0.00
TEST    604 1343230801  all %idle   97.80
TEST    605 1343231401  all %user   0.47
TEST    605 1343231401  all %nice   0.00
TEST    605 1343231401  all %system 1.73
TEST    605 1343231401  all %iowait 0.00
TEST    605 1343231401  all %steal  0.00
TEST    605 1343231401  all %idle   97.79
TEST    604 1343232001  all %user   0.47
TEST    604 1343232001  all %nice   0.00
TEST    604 1343232001  all %system 1.74
TEST    604 1343232001  all %iowait 0.01
TEST    604 1343232001  all %steal  0.00
TEST    604 1343232001  all %idle   97.78


------------------------------------------

반응형

select는 특정 이벤트가 발생하면 running을 하지만 

poll은 계속해서 주기적으로 돌면서 이벤트를 체크한다. 


int poll(struct pollfd *fds, nfds_t nfds, int timeout);


1인자값 : 이벤트 등록 변수

2인자값 : 체크할 pollfd의 개수

3인자값 : time out 시간 


만약에 poll(0, 0, 1000); 이렇게 하면 

sleep(1); 과 같이 1초 delay를 줄 수 있다. 


출처: http://forum.falinux.com/zbxe/?document_srl=405838

위의 페이지에 따르면


POLL함수는 확인하고 싶은 여러가지 이벤트를 미리 등록해놓고 그 이벤트들이 발생했는지

확인할 수 있는 편리한 방법을 제공한다.

POLL 함수의 PHASE는 5단계로 다음과 같다. 


PHASE 1 : 주기적으로  check할 이벤트 등록

PHASE 2 : poll() 함수를 호출한다. 

PHASE 3 : 이벤트가 발생하면 poll()함수 호출 후에 바로 return.

PHASE 4 : 이벤트가 발생하지 않으면, 이벤트 발생할 때까지 time-out 시간 만큼 기다린다. 

PHASE 5 : 이벤트가 발생하면 해당 이벤트 배열 아이템의 값이 바뀌는데 이 값을 가지고 어느 이벤트가 발생했는지 알 수 있다. 


< 서버쪽 예제> ... 클라이언트가 자꾸 제대로 안된다.. OTL..

코드출처 : http://stackoverflow.com/questions/448331/my-simple-poll-example-only-partially-works

-----------------------------------------------


#include 
#include 
#include 
#include 
#include "sys/time.h"
#include "sys/types.h"
#include 
#include 
#include "sys/socket.h"
#include "netinet/in.h"
#include "arpa/inet.h"
#include 

#define PORT 29900 
#define MAX_CONN 10
#define SECOND 1000
#define TIMEOUT (30 * SECOND)

static int listen_socket();

int main(int argc, char **argv)
{
    struct pollfd **my_fds;                  //array of pollfd structures for poll()
    struct pollfd *curr, *new_conn;          //so I can loop through
    int num_fds;                             //count of how many are being used
    int i, j;                                //for loops
    char buff[255], buff2[255];              //for sending and recieving text
    struct sockaddr_in my_addr, their_addr;  // my address information
    socklen_t sin_size;
    int buff_sz;                             //size of data recieved

    printf("App Started\n");

    //allocate space for 10 
    my_fds = (struct pollfd**)calloc( MAX_CONN, sizeof(struct pollfd*));

    //set all the pointers to NULL
    for (i = 0; i < MAX_CONN; i++)
        *(my_fds + i) = NULL;

    //I call listen_socket() which creates a socket to listen to
    //this is anchored into my_fds array at element 0.
    curr = (struct pollfd*) calloc (1, sizeof(struct pollfd));
    curr->fd = listen_socket();
    curr->events = POLLIN;
    curr->revents = 0;

    *my_fds = curr;

    printf("Listening socket fd locked always at position zero in array: %d\n", curr->fd);

    //num_fds, the count of items in the array is set to 1
    //because the listen socket is already present
    num_fds = 1;

    //This is the main loop.
    //While (true)
    //  set all struct pollfd items revents to 0
    //  call poll
   //  loop through, see if there is data to read
    //  read the data
    //  loop through all sockets (except the listen_socket()) and send the data.
    while (1)
    {
        //reset all event flag
        for (i = 1; i < num_fds; i++)
        {
            curr = *(my_fds + i);
            curr->events = POLLIN | POLLPRI;
            printf("%i: fd %i\n", i, curr->fd);
            curr->revents = 0;
            send(curr->fd, "Enter some text:\n", 18, 0);
        }

        //put all this into poll and wait for something magical to happen
        printf("calling poll (%d sockets)\n", num_fds);
        if (poll(*my_fds, num_fds, TIMEOUT) == -1)
        {
            perror("poll");
            exit(0);
        }

        printf("poll returned!\n");

        //First item is the accepting socket....check it independently of the rest!
        curr = *my_fds;
        if (curr->revents != 0)
        {
            printf("We have a new connection.\nAccept goes here...\n");

            //Accept the connection
            sin_size = sizeof their_addr;
            new_conn = (struct pollfd*) calloc(1, sizeof(struct pollfd));
            new_conn->fd = accept(curr->fd, (struct sockaddr *)&their_addr, &sin_size);
            new_conn->events = POLLIN;
            new_conn->revents = 0;

            printf("Connection from %s\n", inet_ntoa(their_addr.sin_addr));
            sprintf(buff, "Your %i\n", num_fds);
            send(new_conn->fd, buff, 255, 0);

            //Add it to the poll call
            *(my_fds + num_fds) = new_conn;
            num_fds++;

        }
        else
        {
            //skip first one, we know that's the accepting socket (handled above).
            for (i = 1; i < num_fds; i++)
            {
                curr = *(my_fds + i);
                if (curr->revents != 0)
                {
                    buff_sz = recv(curr->fd, &buff, 255, 0);
                    buff[buff_sz] = '\0';
                    printf("Recieved: %s", buff);

                    //send the message to everyone else
                    for (j = 1; j < num_fds; j++)
                    {
                        printf("i = %i, j = %i\n", i, j);
                        if (j != i)
                        {
                            new_conn = *(my_fds + j);
                            sprintf(buff2, "%i sent you %i: %s", i, j, buff);
                            send(new_conn->fd, buff2, strlen(buff2) + 1, 0);
                        }
                    }
                }
            }
        }
    }

    printf("App Ended\n");
}

static int listen_socket()
{
    struct sockaddr_in a;
    int s;
    int yes;

    if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        perror("socket");
        return -1;
    }
    yes = 1;
    if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
                (char *) &yes, sizeof(yes)) < 0) {
        perror("setsockopt");
        close(s);
        return -1;
    }
    memset(&a, 0, sizeof(a));
    a.sin_port = htons(PORT);
    a.sin_family = AF_INET;
    if (bind(s, (struct sockaddr *) &a, sizeof(a)) < 0) {
        perror("bind");
        close(s);
        return -1;
    }
    printf("Accepting connections on port %d\n", PORT);
    listen(s, 10);
    return s;
}


-----------------------------------------------


도무지 이해가 안가서 일부분만 떼어왔다.

http://forum.falinux.com/zbxe/?document_srl=405838

struct pollfd poll_events; // 체크할 event 정보를 갖는 struct

poll() 사용하기 위한 변수를 선언.
poll_events
에는 감시 대상인 디스크립터와 어떤 event 감시할지 결정해서 bit 값으로 지정.

int poll_state;

poll() 수행한 결과값. 아래와 같은 반환값.

 

poll() 수행 반환

 

반환

설명

음수

반환 값이 음수라면 치명적인 에러가 발생한 것입니다. 한번 이렇게 음수로 에러가 발생하면 이후 계속 음수값이 날라 옵니다. 거의 대부분 프로그램을 다시 실행해야 됩니다. 반드시 체크해야 겠지요.

0

지정한 대기시간, time-out 지나도록 발생한 event 없습니다.

양수

event 발생했습니다.

 

poll_events.fd = fd;

감시 대상인 디스크립터를 지정.

poll_events.events = POLLIN | POLLERR; // 수신된 자료가 있는지, 에러가 있는지

체크하고 싶은 event 대해 비트값으로 설정하여 지정.

poll_events.revents = 0;

revents 0 으로 초기화.

poll_state = poll(                               // poll() 호출하여 event 발생 여부 확인    
                  (
struct pollfd*)&poll_events, // event 등록 변수
                                             1,  //
체크할 pollfd 개수
                                          1000   // time out
시간
                );

체크할 event 정보를 넘겨 주고, 1 체크할 pollfd 개수.

예제에는 감시하는 디스크립터가 개이지만 프로그램에 따라서는 여러 개의 디스크립터를 관리할 경우가 많음.

 

관리할 디스크립터가 많을 , 각각을 변수로 처리하는 보다 배열로 처리하는 것이 편리.

이래서 poll() 편리.

poll() 변수 하나 외에도 배열을 받을 있으며,

한번의 호출로 모든 event 발생 여부를 확인할 있어 매우 편리.

 

1000 time-out 시간으로 발생한 event 없을 경우

poll() event 발생할 까지 time-out 시간 동안 대기.

 

if ( 0 < poll_state)

poll() 함수 결과가 양수라면 event 발생.

if ( poll_events.revents & POLLIN)

발생한 event 중에 POLLIN 있는 지를 확인.

POLLIN 해당되는 bit 1 세트되어 있다면 POLLIN으로 AND 값은 0 아닐 .

이렇게 비트값을 확인하여 event 발생 여부를 확인.

cnt = read( fd, buf, 1024);

write( fd, buf, cnt);

자료 수신 event 발생했으므로 fd로부터 자료 값을 읽어 들이고,

예제 테스트를 위해 다시 자료를 전송.

 

 

반응형

'Language > C' 카테고리의 다른 글

writev 함수 예제  (8) 2012.07.31
readv 함수 예제  (8) 2012.07.30
GCC 컴파일러 에러 메세지 리스트(Error Message List)  (6) 2012.07.24
select 함수 예제  (8) 2012.07.23
Unix Domain Socket 예제  (6) 2012.07.23

Server측에서 poll 함수를 가지고 주기적으로 돌고 있고

Client측에서 포트번호를 자동적으로 증가시켜가면서 붙는데

도대체 이 포트번호의 범위가 어딘지 모르겠다.

 

그래서 찾아봤다.

 

sysctl이라고 시스템 커널과 관련하여 다양한

설정값을 확인할 수 있다. (루트권한)

 

 

# sysctl -a |grep port
sunrpc.max_resvport = 1023
sunrpc.min_resvport = 665
dev.parport.default.spintime = 500
dev.parport.default.timeslice = 200
net.ipv4.ip_local_port_range = 32768 61000
fs.nfs.nlm_tcpport = 0
fs.nfs.nlm_udpport = 0

 

따라서 요렇게 수행하면 범위가 나온다.

# sysctl -a |grep net.ipv4.ip_local_port_range
net.ipv4.ip_local_port_range = 32768 61000

 

생각보다 간단하게 찾아진다..

반응형

 stadard error가 프로세스 수행하면 막 뜨는데
이걸 파일이나 어디 다른데다가 기록하게 할 수 없는지
방법을 찾아야했는데 이런게 있다. 괜찮네.. 간단하고..

std 관련 설명

[a] stdin - Use to get input (keyboard) i.e. data going into a program.

[b] stdout - Use to write information (screen)

[c] stderr - Use to write error message (screen)

I/O streams 숫자의 의미

The Unix / Linux standard I/O streams with numbers:

Handle

Name

Description

0

stdin

Standard input

1

stdout

Standard output

2

stderr

Standard error

1. stderr 를 file에 쓰는 경우

만약에error.log 파일에 stderr를 쓰려면

아래처럼 수행한다:

$ program-name 2> error.log

$ command1 2> error.log

2. stderr 와 stdout 을 file에 쓴다.

아래처럼 수행한다:

$ command-name &>file

혹은:

$ command > file-name 2>&1

다른 방식으로 하려면:

# find /usr/home -name .profile 2>&1 | more

3. stderr 를 stdout 으로

아래처럼 수행한다:

$ command-name 2>&1

반응형

이 문서는 GCC Version 2.7.2를 기준으로 하여 이 컴파일러가 출력하는 에러 [error]와 경고 [warning] 메시지를 한국어로 번역하고, 그 메시지를 발생할 수 있는 간단한 예제를 보이며, 간단한 해결책을 제시합니다.

 

GCC Error (Warning) Message List

Copyright © 1999 Seong-Kook Cin

   Seong-Kook Cin Jang-Chon Dong 21-2 Sun-Chon City 540-190 South KOREA

   

Before reading this

이 문서는 GCC Version 2.7.2를 기준으로 하여 이 컴파일러가 출력하는 에러 [error]와 경고 [warning] 메시지를 한국어로 번역하고, 그 메시지를 발생할 수 있는 간단한 예제를 보이며, 간단한 해결책을 제시합니다.

이 문서는 C 배우미들이 낯선 컴파일러 메시지를 만났을 때 당황하지 않고 쉽게 문제를 해결할 수 있기를 바라는 뜻에서 만들어진 것입니다.

이 문서는 유용하게 쓰여지기를 바라면서 만들어졌지만 저자는 이 문서에 대해 어떠한 보증도 하지 않습니다. 즉, 이 문서에 의해 일어날 수 있는 손해에 대해서는 책임을 지지 않습니다.

이 문서는 GCC가 발생할 수 있는 에러 메시지를 모두 포함하지 않을 수도 있습니다. 여러분이 이 문서에 없는 에러 메시지를 발견해서, 이 문서에 추가하기를 원하거나, 이 문서에 틀린 곳을 수정하기를 원한다면

cinsk@acm.org 으로 e-mail을 보내시기 바랍니다. 어떠한 제안이나 비판도 환영합니다. 저자는 여러분들의 참여로 이 문서가 보다 완전해지기를 원합니다.

   

Conventions

영어를 한국어로 쓸 때, 한국어를 영어로 표기할 때 혼동을 가져올 수 있는 용어나 기타 부가적인 설명은 그 용어 뒤의 `[]'안에 옵니다. 문서의 형식은 다음과 같습니다.

에러 메시지

에러 메시지 설명......................

이 에러 메시지를 발생시키는 예제

   

파일:줄 번호: 실제 컴파일러가 발생하는 에러 메시지

   

Table of Contents

Errors

   

   

   

   

   

   

   

   

Warnings

   

   

   

   

   

   

   

warning: initializer-string for array of chars is too long

주어진 배열이 가질 수 있는 문자의 개수보다 많은 초기값이 주어진 경우에 발생합니다. C 언어의 문자열은 큰 따옴표(`"')로 둘러싸서 나타내며 문자열의 끝을 나타내기 위해 ASCII 코드 0번 문자(`\0')를 사용합니다. 따라서 아래의 예에서 배열 `ca'는 크기가 5로 되어 있어야 합니다.

문자열 배열을 쓸 때마다 이런 식으로 배열의 크기를 지정해 주는 것은 번거로운 일입니다. 배열이 초기값을 가지고 있을 때에는 배열의 크기를 지정하지 않아도(`ca[]') 좋습니다.

char ca[3] = "abcd";

   

file:1: warning: initializer-string for array of chars is too long

   

invalid #-line

라인 [line] 번호 정보를 잘못 입력한 경우에 발생합니다. 라인 번호는 0보다 큰 양수 [positive number]이어야 합니다.

invalid format `#line' directive 에러를 참고하시기 바랍니다.

# 0 "foo.c"

   

file:1: invalid #-line

또는,

#line 0

   

file:1: invalid #-line

   

parse error before `XXX'

이 에러가 발생하는 조건은 너무나도 많습니다. 일반적으로 문장을 분석 [parse]할 때 예상하지 못한 구문을 발견했을 경우에 이 에러가 발생합니다. parse error 에러를 참고하기 바랍니다.

조건 1: typedef로 정의한 형에 short, long, signed, unsigned 등을 사용할 때.

typedef int INT;

unsigned INT ui;

   

file:2: parse error before `ui'

file:2: warning: data definition has no type or storage class

조건 2:

void f()

{

else {

}

}

   

file: In function `f':

file:3: parse error before `else'

   

warning: `XXX' redefined

사용자가 정의한 매크로를 다시 정의하거나, ANSI C 혹은 컴파일러가 미리 정의해 놓은 매크로를 재 정의하려 할 때 발생합니다. 사용자가 정의한 매크로인 경우, #undef 지시어를 써서 이 경고를 없앨 수 있습니다.

#define MY_CONST "cinsk"

#define MY_CONST "windy"

   

file:2: warning: `MY_CONST' redefined

   

warning: undefining `XXX'

ANSI C 혹은 컴파일러가 미리 정의해 놓은 매크로(predefined macro)를 없앨 경우에 발생합니다. 이 경고가 발생할 경우, 여러분은 다른 매크로를 써야 합니다. 미리 정의된 매크로를 다른 목적으로 쓰는 것은 좋지 않습니다. ANSI C 혹은 컴파일러가 미리 정의해 놓은 상수 목록은 컴파일러와 함께 제공되는 매뉴얼을 참고하시기 바랍니다.

#undef __FILE__

   

file1: warning: undefining `__FILE__'

   

ANSI C requires a named argument before `...'

ANSI C는 하나 이상의 가변 인자 [variable length argument]를 받을 수 있게 하지만 하나 이상의 고정된 인자가 있어야 합니다. 아래의 예에서 함수 f()는 고정된 인자가 하나도 없기 때문에 이 에러가 발생합니다.

void f(...) { }

   

file:1: ANSI C requires a named argument before `...'

   

unterminated macro call

주어진 매크로의 인자를 읽을 때 괄호가 닫히지 않을 경우 이 에러가 발생합니다.

#define NOP(x)

NOP(foo

   

file:2: unterminated macro call

   

duplicate argument name `XXX' in `#define'

매크로를 정의할 때 같은 이름을 두 인자에 대해 썼을 경우 이 에러가 발생합니다.

#define ADD3(a, a, c) ((a) + (b) + (c))

   

file:1: duplicate argument name `a' in `#define'

   

parse error

어구 분석(parsing)에 실패했을 경우 이 에러가 발생합니다. 이 에러가 발생하는 경우는 매우 많습니다. parse error before `XXX' 에러를 참고하기 바랍니다.

조건 1: `#elif' 다음에 상수식이 오지 않을 때

#if defined(ONE)

int i = 1;

#elif

int i = 2;

#endif

   

file3: parse error

조건 2: 비어있는 매크로를 잘못 썼을 때.

#define EMPTY

#if EMPTY

char *msg = "EMPTY is non-empty";

#endif

   

file:2: parse error

   

empty character constant

빈 문자 상수가 쓰였을 때 이 에러가 발생합니다.

int i = '';

   

file:1: empty character constant

   

empty file name in `#include'

`#include' directive에서 파일 이름이 주어지지 않았을 때 발생합니다.

#include <>

   

file:1: empty file name in `#include'

   

unbalanced `#endif'

`#endif' directive가 if 섹션 ('#if', `#ifdef', `#ifndef' 등으로 시작하는) 과 맞게 쓰이지 않을 때 발생합니다.

#endif

   

file:1: unbalanced `#endif'

   

warning: declaration of `xxx' shadows a parameter

int f(int i)

{

enum e { l, j, k, i};

}

   

file: In function `f':

file:3: warning: declaration of `i' shadows a parameter

file:4: warning: control reaches end of non-void function

   

warning: integer overflow in expression

정수로 취급되는 식 (enumerator 포함)에서 오버플로우(overflow)가 일어날 경우에 이 경고가 발생합니다.

#include

   

enum A { AA = INT_MAX + 1 };

   

file:3: warning: integer overflow in expression

   

#error XXX

이 에러는 컴파일러에게 소스가 전달되기 전, 프리프로세서(preprocessor)에 의해 발생합니다. 프리프로세서는 `#error'로 시작하는 문장을 만나면 바로 컴파일 작업을 중단하고 `#error' 문장을 출력합니다. 이는 대개 프로그램 소스가 특별한 환경을 요구하는 경우, 적합하지 않은 환경일 때에는 컴파일이 되지 않게 하기 위한 목적으로 쓰입니다.

ANSI C에서는 몇 개의 미리 정의된(predefined) 상수를 정의하고 있고, 컴파일러에 따라서 추가적인 상수를 제공합니다. `#error'의 경우, 이들 상수와 같이 쓰이는 경우가 일반적이므로, 자세한 것은 컴파일러의 매뉴얼을 참고하시기 바랍니다.

#ifndef NEVER_DEFINED

#error NEVER_DEFINED required

#endif

file:2: #error NEVER_DEFINED required

   

parameter name omitted

int f(int)

{

return 0;

}

   

file:1: parameter name omitted

   

`XXX' declared as function returning an array

int f(void)[];

   

file:1: `f' declared as function returning an array

   

called object is not a function

void f(void)

{

char *p;

p();

}

   

file: In function `f':

file:4: called object is not a function

   

   

warning: `return' with no value, in function returning non-void

int f(void)

{

return;

}

   

file: In function `f':

file:3: warning: `return' with no value, in function returning non-void

   

file

   

unterminated character constant

문자 상수가 `''로 닫히지 않을 경우에 발생합니다.

char ch = 'a;

   

file:1: unterminated character constant

   

unterminated comment

주석 [comment]이 `/*'로 닫히지 않을 경우에 발생합니다.

/* This is a comment

   

file:1: unterminated comment

   

unterminated string or character constant

문자 상수나 문자열이 `"'로 끝나지 않을 경우에 발생합니다.

char *str = "cinsk\

the wind

   

file:1: unterminated string or character constant

file:2: possible real start of unterminated constant

   

possible real start of unterminated constant

문자 상수나 문자열이 `"'로 끝나지 않을 경우에 발생합니다.

char *str = "hello\

world

   

file:1: unterminated string or character constant

file:2: possible real start of unterminated constant

   

warning: return-type defaults to `int'

함수의 리턴 형 [return type]을 생략할 경우에 발생합니다. 리턴 형이 생략된 함수의 리턴 형은 `int'입니다.

foo(void)

{

return 0;

}

   

file:2: warning: return-type defaults to `int'

   

warning: control reaches end of non-void function

함수의 리턴 형 [return type]이 `void'가 아닌데도 함수가 `return' 문을 가지지 않을 경우에 발생합니다. 이 경우 함수를 `void' 형으로 선언하거나 `return' 문을 쓰면 해결됩니다.

int foo(void) {}

   

file:1: warning: control reaches end of non-void function

   

warning: dereferencing `void *' pointer

void 형 포인터 [pointer]는 다른 형 포인터로 캐스트 [cast]하기 전에는 쓸 수 없습니다. 즉, 이 에러는 void 형 포인터에 역참조 [dereference] 연산자인 `*'를 썼기 때문에 발생합니다. 이 에러를 해결하려면 void 형 포인터를 다른 형 포인터 (예를 들어 `int *')로 캐스팅 [casting]해서 쓰면 됩니다.

void foo(void)

{

void *p, *q;

*(p = q);

}

   

file:4: warning: dereferencing `void *' pointer

file:4: warning: value computed is not used

   

dereferencing pointer to incomplete type

정의되지 않은 형을 가리키는 포인터 [pointer]에 역참조 [dereference] 연산자(`*')를 쓸 수 없습니다.

struct s;

void g(struct s *);

void f(void)

{

struct s *p;

g(*p);

}

   

file:6: dereferencing pointer to incomplete type

   

warning: passing arg N of `XXX' makes integer from pointer without a cast

함수 XXX의 N번째 파라메터 [parameter]가 정수형인데도 캐스팅 [casting]없이 포인터를 인자 [argument]로 쓴 경우에 발생합니다.

void f(int);

void g(void)

{

f("erroneous");

}

   

file:4: warning: passing arg 1 of `f' makes integer from pointer without a cast

   

int f(char *);

void g()

{

f(5);

}

   

file: In function `g':

file:4: warning: passing arg 1 of `f' makes pointer from integer without a cast

   

   

incompatible type for argument N of `XXX'

함수 선언에 쓰인 파라메터 [parameter]의 형과 실제 인자 [argument]의 형이 서로 달라서 변경할 수 없는 경우에 발생합니다.

struct s { int a; } p;

void f(void)

{

void g(int, int);

g(5, p);

}

   

file:5: incompatible type for argument 2 of `g'

   

too few arguments to function `XXX'

함수 선언에 쓰인 파라메터 [parameter]의 수보다 실제 인자 [argument]의 개수가 적을 경우에 발생합니다.

void f(void)

{

void g(int, int);

g(5);

}

   

file:4: too few arguments to function `g'

   

too many arguments to function `XXX'

함수 선언에 쓰인 파라메터 [parameter]의 수보다 실제 인자 [argument]의 개수가 많을 경우에 발생합니다.

void f(void)

{

void g(int);

g(5, 2);

}

   

file:4: too many arguments to function `g'

   

incompatible types in assignment

대입 [assignment] 연산에서 연산자 `=' 사이의 오퍼랜드 [operand]의 형이 서로 완전히 다릅니다. assignment makes integer from pointer without a cast 경고를 참고하시기 바랍니다.

struct s {};

void f()

{

struct s st;

int i;

i = st;

}

   

file:7: incompatible types in assignment

   

warning: assignment makes integer from pointer without a cast

대입 [assignment] 연산에서 연산자 `=' 양쪽에 오는 오퍼랜드 [operand]가 왼쪽은 정수형, 오른쪽은 포인터일 경우에 이 경고가 발생합니다. 이를 해결하려면 포인터를 정수형으로 캐스팅 [casting]해야 합니다. incompatible types in assignment 에러를 참고하시기 바랍니다.

void f()

{

char *cp;

int i;

i = cp;

}

   

file:5: warning: assignment makes integer from pointer without a cast

   

top-level declaration of `XXX' specifies `auto'

함수 바깥에 선언된 선언에 `auto' 키워드가 쓰였습니다. `auto' 키워드는 자동 변수 [automatic variable]를 선언하기 위해 쓰는 것이므로 전역 변수 [global variable]에 쓰일 수 없습니다.

auto int i;

   

file:1: top-level declaration of `i' specifies `auto'

   

register name not specified for `XXX'

`register' 키워드는 자주 쓰이는 변수를 메모리 대신 (가능하다면 [if possible]) CPU의 레지스터 [register]를 쓰도록 합니다. 전역 변수 [global variable]에는 `register' 키워드를 쓸 수 없습니다.

register int i;

   

file:1: register name not specified for `i'

   

redeclaration of `XXX'

같은 스코프 [scope] 안에 같은 이름이 쓰인 경우에 발생합니다. 다른 변수 이름을 써야 할 것입니다. 이 에러는 `XXX' previously declared here 에러와 함께 발생합니다.

void foo()

{

int i;

int i;

i = 3;

}

   

file:4: redeclaration of `i'

file:3: `i' previously declared here

   

`XXX' previously declared here

같은 스코프 [scope] 안에 같은 이름이 쓰인 경우에 처음 선언한 곳을 나타내 줍니다. 이 에러는 redeclaration of `XXX' 에러와 함께 발생합니다.

void foo()

{

int i;

int i;

i = 3;

}

   

file:4: redeclaration of `i'

file:3: `i' previously declared here

   

`#include' expects "FILENAME" or <FILENAME>

`#include'에 쓰이는 파일 이름은 `"'나 `<>'로 둘러싸야 합니다.

#include stdio.h

   

file:1: `#include' expects "FILENAME" or <FILENAME>

   

numeric constant contains digits beyond the radix

주어진 수치 상수 [numeric constant]가 진법에 맞지 않을 경우에 발생합니다. 예를 들어 8 진수에서 쓰일 수 있는 숫자는 0, 1, ..., 7인데 아래의 예처럼 8을 쓴다거나, 16 진수에서 쓰일 수 있는 문자는 a, b, ..., f인데 f 이후의 문자를 쓸 경우에 발생합니다.

int i = 08;

int j = 0xah;

   

file:1: numeric constant contains digits beyond the radix

file:2: numeric constant contains digits beyond the radix

   

`#' operator is not followed by a macro argument name

`#' 매크로 연산자는 매크로 인자 [argument] 앞에 나와 이 이 인자를 문자열 [string]로 만들어주는 역할을 합니다. `#' 연산자가 매크로 이름 앞에 나오지 않은 경우에 이 에러가 발생합니다.

#define bug(s)        s #

   

file:1: `#' operator is not followed by a macro argument name

   

`##' at start of macro definition

`##' 매크로 연산자는 두 개의 인자 [argument]를 받아 이들을 하나의 토큰 [token]으로 바꾸어 줍니다. 따라서 `##' 연산자는 `+' 연산자처럼 쓰이며 양쪽에 인자가 와야 합니다. `##' 연산자 앞에 인자가 오지 않을 때 이 에러가 발생합니다.

#define bug(s)        ## s

   

file:1: `##' at start of macro definition

   

`##' at end of macro definition

`##' 매크로 연산자는 두 개의 인자 [argument]를 받아 이들을 하나의 토큰 [token]으로 바꾸어 줍니다. 따라서 `##' 연산자는 `+' 연산자처럼 쓰이며 양쪽에 인자가 와야 합니다. `##' 연산자 뒤에 인자가 오지 않을 때 이 에러가 발생합니다.

#define bug(s)        s ##

   

file:1: `##' at end of macro definition

   

`XXX' defined as wrong kind of tag

struct이나 union, enum을 써서 한 형을 만들때, 이 때 사용한 tag (예를 들어 struct s;에서 tag는 `s'가 됩니다.)가 다른 타입에서 쓰일 때 이 에러가 발생합니다.

struct s { int x, y, z; };

void f()

{

union s foo;

foo.x = 1;

}

   

file:4: `s' defined as wrong kind of tag

   

negative width in bit-field `XXX'

bit field에서 bit 갯수를 지정할 때 음수 [negative number]나 0을 쓸 수 없습니다.

struct s { int x : -3; };

   

file:1: negative width in bit-field `x'

   

warning: width of `XXX' exceeds its type

Bit field의 크기가 주어진 형의 크기를 넘을 경우 발생합니다. 크기가 큰 다른 형으로 바꾸거나 bit field의 크기를 줄여 해결할 수 있습니다.

struct s { char c : 20; };

   

file:1: warning: width of `c' exceeds its type

   

break statement not within loop or switch

`break' 키워드는 switch, while, do-while, for 내부에서만 쓰일 수 있습니다. `break'를 다른 곳에서 쓸 경우 이 에러가 발생합니다.

void f()

{

break;

}

   

file:3: break statement not within loop or switch

   

request for member `XXX' in something not a structure or union

`.' 연산자는 구조체 [structure]나 union에서 멤버 [member]를 엑세스하기 위해 사용하며, 구조체나 union이 아닌 곳에서 `.'를 사용할 경우에 이 에러가 발생합니다. 대개의 경우, 구조체의 이름을 틀리게 썼을 경우에 발생합니다.

struct s { int i; };

void f()

{

char c;

c.i = 3;

}

   

file:5: request for member `i' in something not a structure or union

   

char-array initialized from wide string

C 언어는 여러 나라의 언어를 지원하기 위해 multibyte 문자인 wide character를 지원합니다. Wide character 상수는 문자 상수나 문자열 앞에 'L'을 붙여 나타내며 이 형은 wchar_t (<stddef.h>에 정의되어 있습니다) 입니다. 이 에러는 wchar_t 형 문자열을 char 형 배열에 초기값으로 쓸 때 발생합니다. 배열을 wchar_t 형으로 선언하거나 초기값을 char 형 상수를 써서 이 에러를 해결할 수 있습니다.

char a[] = L"abc";

   

file:1: char-array initialized from wide string

   

declaration of `XXX' as array of voids

void 형은 포인터 형으로 쓰거나 함수의 return 값으로 쓰이는 경우에만 의미가 있습니다. 다른 경우, 예를 들어 void 형 배열을 선언하는 것은 옳지 않습니다.

void a[3];

   

file:1: declaration of `a' as array of voids

   

invalid macro name `defined'

프리프로세서 [preprocessor]의 연산자인 `defined'는 매크로 이름으로 정의될 수 없으며, 정의를 취소할 수도 없습니다.

invalid macro name `XXX' 에러를 참고하시기 바랍니다.

#undef defined

#define defined        abc

   

file:1: invalid macro name `defined'

file:2: invalid macro name `defined'

   

#undef 4

   

file:1: invalid macro name `4'

   

invalid type argument of `unary *'

단항 연산자 [unary operator] `*'는 포인터 앞에서 이 포인터가 가리키는 것을 역참조 [dereference]하기 위해 쓰입니다. `*' 연산자가 포인터가 아닌 다른 형에 쓰이면 이 에러가 발생합니다.

void f()

{

int i;

*i = 3;

}

   

file:4: invalid type argument of `unary *'

   

arithmetic on pointer to an incomplete type

아직 완전하게 정의가 알려지지 않은 형에 대해서 포인터 연산을 수행할 수 없습니다. 아래의 예에서 이 에러가 발생하지 않게 하려면 먼저 `struct s' 형의 정의를 내려야 합니다.

struct s;

void g(struct s*);

void f()

{

struct s *p;

g(p + 1);

}

   

file:6: arithmetic on pointer to an incomplete type

   

XXX: No such file or directory

`#include'에서 쓴 파일을 찾을 수 없을 때 이 에러가 발생합니다. 대개 이 에러는 사용자가 만든 파일을 `"' 대신 `<>'로 둘러싸거나 파일 이름을 틀리게 입력하거나, 또는 컴파일러 옵션에서 디렉토리 설정이 잘못되어 있는 경우, 컴파일러에서 쓰이는 환경 변수 [environment variable]가 잘못 지정되어 있는 경우에 발생합니다. 자세한 것은 GCC 문서(info)에서 `-I' 옵션이나 `C_INCLUDE_PATH' 환경 변수를 참고하시기 바랍니다.

#include <where_is_it.h>

   

file:1: where_is_it.h: No such file or directory

   

variable or field `XXX' declared void

변수나 field는 void 형으로 선언할 수 없습니다.

저자가 쓰고 있는 GCC 2.7.2는 전역 변수 [global variable]로 `void a;'를 선언하면 이 에러를 만들지 않습니다. 이는 버그인 것으로 생각되는데, 이 문제에 대해 도움을 주실 수 있는 분은 알려 주시면 감사하겠습니다. 연락처는 이 문서의 처음에 있습니다.

void foo()

{

void a;

}

   

file:3: variable or field `a' declared void

file:4: warning: unused variable `a'

   

`XXX' has both `extern' and initializer

함수의 내부에서 `extern'으로 선언된 오브젝트 [object]는 초기값 [initializer]을 가질 수 없습니다. `XXX' initialized and declared `extern' 경고를 참고하시기 바랍니다.

extern int i = 1;

void f()

{

extern int j = 3;

}

   

file:1: warning: `i' initialized and declared `extern'

file: In function `f':

file:4: `j' has both `extern' and initializer

tmp.c:4: warning: unused variable `i'

   

warning: `XXX' initialized and declared `extern'

`extern'으로 선언된 오브젝트 [object]에 초기값 [initializer]을 주면 `extern'은 무시됩니다. `XXX' has both `extern' and initializer 에러를 참고하시기 바랍니다.

extern int i = 1;

void f()

{

extern int j = 3;

}

   

file:1: warning: `i' initialized and declared `extern'

file: In function `f':

file:4: `j' has both `extern' and initializer

tmp.c:4: warning: unused variable `i'

   

function `XXX' is initialized like a variable

함수로 선언 [declaration]된 이름은 초기값 [initializer]을 가질 수 없습니다.

int f(void) = 3;

   

file:1: function `f' is initialized like a variable

   

parameter `XXX' is initialized

예전 방식 [old style]으로 선언된 함수에서 파라메터 [parameter]는 초기값 [initializer]을 가질 수 없습니다.

void f(i)

int i = 3;

{

}

   

file:2: parameter `i' is initialized

   

typedef `XXX' is initialized

`typedef'는 기존의 형에 대해 새 형 이름 [type name]을 정의하는 것이기 때문에 초기값 [initializer]을 가질 수 없습니다.

typedef int INT = 1;

   

file:1: typedef `INT' is initialized

   

No such file or directory

컴파일러가 주어진 파일 이름 (디렉토리 포함)을 찾을 수 없을 때 발생합니다. 대개 파일 이름을 틀리게 입력했을 때 발생합니다.

gcc where_is_it.c

   

where_is_it.c: No such file or directory

   

macro or `#include' recursion too deep

매크로나 `#include'가 재귀적으로 너무 깊게 반복될 때 발생합니다. 예를 들어 `util.h'가 `types.h'를 포함 (#include)하고, `types.h'가 다시 `util.h'를 포함하는 경우, 이들 파일을 소스에 포함시키면, 서로가 서로를 계속 포함시키게 되므로 결국 컴파일러는 이 에러를 발생시킵니다. 이럴 때에는 `#ifndef', `#define', `#endif' 등을 써서 재귀적으로 포함되지 않게 해서 해결합니다.

#include "util.h"

   

file:1: macro or `#include' recursion too deep

   

invalid use of undefined type `XXX'

주어진 형이 완전히 정의되지 않은 상태에서 이 형을 사용할 수 없습니다. 아래의 예에서는 함수 g()의 return 형이 `struct s'이지만 `struct s'는 아직 정의되지 않았습니다. 이 때 g()를 부르는 것은 옳지 않습니다. 이 문제를 해결하려면 함수 g()를 부르기 전에 먼저 `struct s'를 정의해야 합니다.

void f()

{

struct s g();

g();

}

   

file:4: invalid use of undefined type `struct s'

   

attempt to take address of bit-field structure member `XXX'

Bit field에는 `address of' 연산자인 `&'를 쓸 수 없습니다.

struct s { int i : 3; };

void f()

{

struct s p;

int *ip = &p.i;

}

   

file:5: attempt to take address of bit-field structure member `i'

file:5: warning: unused variable `ip'

   

warning: address of register variable `XXX' requested

`register'로 선언 [declaration]된 변수에 `address of' 연산자를 쓸 경우에 발생합니다. `register'를 쓴다고 항상 CPU의 레지스터에 이 변수가 저장되는 것은 아니지만, 실제 CPU 레지스터의 사용 여부에 상관없이 `register'를 쓴 변수의 주소를 얻는 것은 옳지 않습니다.

void f()

{

register int i;

int *ip = &i;

ip = 0;

}

   

file:4: warning: address of register variable `i' requested

   

`sizeof' applied to a bit-field

Bit-field에는 `sizeof' 연산자를 쓸 수 없습니다.

struct s { int i : 3; };

void f()

{

struct s p;

int i = sizeof(p.i);

i = 3;

}

   

file:5: `sizeof' applied to a bit-field

   

warning: case value out of range

`case'에서 쓴 상수식 [constant expression]은 `switch'에서 쓴 데이터 형의 범위를 넘을 수 없습니다. 아래의 예에서는 `case'의 상수식 0xffffff가 `char' 형의 범위를 넘었기 때문에 발생합니다. 이 문제를 해결하려면 `switch'에서 쓴 데이터의 형을 좀 더 큰 형 (예를 들어 `int')으로 바꾸어야 합니다.

void f()

{

char c;

switch (c) {

case 0xffffff:

;

}

}

   

file:5: warning: case value out of range

   

case label not within a switch statement

`case'는 `switch' 구조 안에서만 쓸 수 있습니다.

void f()

{

case 4:

;

}

   

file:3: case label not within a switch statement

   

character constant too long

정수안에 들어가기에는 너무 많은 문자를 가지고 있는 상수를 쓸 때에 이 에러가 발생합니다.

int i = 'abcde';

   

file:1: character constant too long

   

warning: escape sequence out of range for character

문자 상수나 문자열에 쓰인 escape sequence가 너무 큰 값을 가지고 있어 문자 [unsigned char]로 표현할 수 없을 때 이 경고가 발생합니다. 이러한 값들은 적절하게 잘라내 [truncate] 버립니다.

char *p = "\x1ff\400";

   

file:1: warning: escape sequence out of range for character

file:1: warning: escape sequence out of range for character

   

continue statement not within a loop

`continue' 키워드는 루프 [loop] (for, while, do-while) 안에서만 의미가 있습니다. `continue'를 루프 밖에서 쓰는 것은 옳지 않습니다.

void foo()

{

continue;

}

   

file:3: continue statement not within a loop

   

invalid operands to binary X

X는 바이너리 연산자 (예: +, -, *, /, ==, !=, <=, >= 등)이며, 연산자의 오퍼랜드 형은 스칼라 [scalar] 형이어야 합니다. 즉 정수나 실수이어야 하며, 구조체 [structure]나 union 형이 올 수 없습니다.

이 에러는 조건식 [conditional expression]이 필요한 if, for, while, do-while 등에서 구조체나 union형을 쓸 때에도 발생합니다.

또 이 에러는 형이 다른 포인터에 연산을 취할 때에도 발생할 수 있습니다.

struct s { int i; };

void f()

{

struct s p;

int i = (p != 0);

   

while (p) {

}

}

   

file: In function `f':

file:5: invalid operands to binary !=

file:7: invalid operands to binary !=

file:5: warning: unused variable `i'

   

void f()

{

char *cp;

int *ip;

int i;

i = ip - cp;

}

   

file: In function `f':

file:6: invalid operands to binary -

이 에러는 조건식인 `? :'을 쓸 때에도 발생합니다. 조건식 `e1 ? e2 : e3'는 `e1'이 참일 경우, `e2'가 평가되고, 거짓일 때에는 `e3'가 평가됩니다. 이 때 이 조건식은 `if (e1 != 0) e2 else e3'로 취급되므로 만약 `e1'이 스칼라 형이 아니면 이 에러가 발생합니다.

struct s { int x; } st;

   

void f(void)

{

int i = st ? 3 : 4;

}

   

file: In function `f':

file:5: invalid operands to binary !=

file:5: warning: unused variable `i'

   

warning: overflow in implicit constant conversion

주어진 상수를 함축적으로 [implicitly] 변환 [conversion]할 때 오버플로우 [overflow]가 발생할 때 이 경고가 발생합니다. 아래의 예는 `int' 형의 범위를 넘는 실수 상수 (double 형)를 `int' 형에 대입하려 하는 경우를 나타냅니다.

int i = 1e300;

   

file:1: warning: overflow in implicit constant conversion

   

warning: declaration of `XXX' shadows a parameter

함수 내부에서 이 함수에 전달되는 파라메터 [parameter]와 같은 이름을 선언한 경우에 발생합니다. 즉 파라메터의 이름이 새 선언 [declaration]에 의해 가려졌으므로 이 선언이 나온 다음부터는 이 이름을 가진 파라메터를 쓸 수 없습니다. 이 경우, 둘 중 하나를 다른 이름을 갖게 고치는 것이 좋습니다.

void f(int i, int INT)

{

int i;

i = 3;

}

   

file:3: warning: declaration of `i' shadows a parameter

   

warning: data definition has no type or storage class

데이터 (함수나 변수등)를 정의할 때 형을 쓰지 않을 경우 발생합니다. 일반적으로 함수나 변수의 return 형을 쓰지 않을 때 발생하며, 이 때에는 `int' 형으로 간주됩니다.

i;

f();

   

file:1: warning: data definition has no type or storage class

file:2: warning: data definition has no type or storage class

   

default label not within a switch statement

`default' 키워드는 `switch' 문 [statement] 안에서만 쓸 수 있습니다.

void f()

{

default:

;

}

file:3: default label not within a switch statement

   

invalid macro name `XXX'

매크로 이름은 유효한 [valid] C 언어 이름 [identifier]이 나와야 합니다. 즉 첫글자는 [_a-zA-Z]이며, 두번째 글자부터는 [_a-zA-Z0-9]입니다. 아래의 예에서 `3'은 이름 [identifier]이 될 수 없기 때문에 이 에러가 발생합니다.

invalid macro name `defined' 에러도 참고하시기 바랍니다.

#define 3

   

file:1: invalid macro name `3'

   

invalid format `#line' directive

`#line' 지시어 [directive] 뒤에는 라인 번호를 의미하는 수치가 나와야 합니다. 이 수치는 0이 아닌 양수 [positive number]이어야 합니다.

invalid #-line 에러를 참고하시기 바랍니다.

#line 02a

   

file:1: invalid format `#line' directive

   

warning: unknown escape sequence `\x'

문자열에서 `\' 뒤에 오는 문자는 특정한 뜻이 있는 몇 개의 문자만 쓸 수 있습니다. 예를 들어 `\n'은 newline 문자를 나타내고, `\t'는 tab 문자를 나타냅니다. 이를 `escape sequence'라고 하며, 알려지지 않은 문자가 `escape sequence'로 쓰인 경우 이 경고가 발생합니다. 이 때 쓰인 `\x'는 일반 문자 `x'로 취급됩니다.

int i = '\q';

   

file:1: warning: unknown escape sequence `\q'

   

duplicate case value

두 `case' 문장에서 같은 상수 값이 쓰였을 때 발생합니다.

void f()

{

int a = 3;

switch (a) {

case 1:

case 1:

default:

break;

}

}

   

file: In function `f':

file:6: duplicate case value

file:5: this is the first entry for that value

   

   

multiple default labels in one switch

`switch' 문장 안에서 `default' 레이블이 두 개 이상 쓰였을 경우 발생합니다.

void f()

{

int a = 3;

switch (a) {

case 1:

default:

default:

break;

}

}

   

file: In function `f':

file:7: multiple default labels in one switch

file:6: this is the first default label

   

duplicate member `XXX'

`struct'이나 `union'에서 같은 이름이 두 개 이상의 멤버에 쓰였을 때 이 에러가 발생합니다. 각각 다른 이름을 써서 이 에러를 없앨 수 있습니다.

struct s {

int i;

float i;

};

   

file:3: duplicate member `i'

   

`#elif' after `#else'

선택적 컴파일을 할 수 있는 `preprocessor directive'인 `#if', `#elif', `#else', `#endif'에서 `#elif'는 항상 `#else' 앞에 나와야 합니다.

#if defined(ONE)

int i = 1;

#elif defined(TWO)

int i = 2;

#else

int i = 3;

#elif defined(FOUR)

int i = 4;

#endif

   

file:7: `#elif' after `#else'

(matches line 1)

   

   

`#XXX' not within a conditional

`Preprocessor directive'인 `#else'나 `#elif'는 `#if'나 `#ifdef', `#ifndef' 등의 if 섹션의 일부로 쓰여져야 합니다. `#elif'가 단독으로 쓰였을 경우 이 에러가 발생합니다.

#elif defined(TWO)

int i = 2;

#endif

   

file:1: `#elif' not within a conditional

file:3: unbalanced `#endif'

   

   

#else

int i = 2;

#endif

   

file:1: `#else' not within a conditional

file:3: unbalanced `#endif'

   

   

invalid initializer

`struct'이나 `union'의 초기값을 중괄호({})로 싸지 않는 등, 잘못된 초기값을 썼을 때 이 에러가 발생합니다.

struct s {

int x;

int y;

} st = 1;

   

file:4: invalid initializer

   

enumerator value for `AA' not integer constant

Enumerator로 쓰일 수 있는 상수는 반드시 정수형 값을 가져야 합니다. 실수(real)나 다른 상수가 아닌 값이 쓰이면 이 에러가 발생합니다.

enum A { AA = 0.1, BB = 2 };

   

file:1: enumerator value for `AA' not integer constant

   

warning: parameter names (without types) in function declaration

함수의 선언은 ANSI 방식과 옛 방식 중 하나를 쓸 수 있습니다. 옛 방식은 함수의 인자 리스트를 쓰지 않고, ANSI 방식은 인자의 타입과 갯수를 꼭 지정해야 합니다. 아래의 예에서는 함수 f의 인자인 `i'의 타입을 지정하지 않았기 때문에 이 경고가 발생한 것입니다.

int f(i);

   

file:1: warning: parameter names (without types) in function declaration

   

undefined or invalid # directive

#abc

   

file:1: undefined or invalid # directive

   

invalid preprocessing directive name

# 0x12

   

file:1: invalid preprocessing directive name

   

   

conflicting types for `XXX'

int i;

long i;

   

file:2: conflicting types for `i'

file:1: previous declaration of `i'

   

   

redefinition of `XXX'

int i = 0;

int i = 1;

   

file:2: redefinition of `i'

file:1: `i' previously defined here

   

   

empty #if expression

#if

int i = 2;

#endif

   

file:1: empty #if expression

   

unterminated `#if' conditional

#ifdef A

int i = 1;

   

file:1: unterminated `#if' conditional

   

warning: `#ifdef' with no argument

#ifdef

int i = 1;

#endif

   

file:1: warning: `#ifndef' with no argument

   

#ifndef

int i = 1;

#endif

   

warning: implicit declaration of function `XXX'

void f()

{

g();

}

   

file:3: warning: implicit declaration of function `g'

   

void value not ignored as it ought to be

int f()

{

void g();

   

int i = (int)g();

return i;

}

   

file: In function `f':

file:5: void value not ignored as it ought to be

   

   

structure has no member named `XXX'

struct abc {

int a, b;

};

   

void f()

{

struct abc a;

a.c = 0;

}

   

cf. union도 같음

file: In function `f':

file:8: structure has no member named `c'

   

   

warning: initialization makes integer from pointer without a cast

int i = "abc";

   

file:1: warning: initialization makes integer from pointer without a cast

   

badly punctuated parameter list in `#define'

#define max(a

   

file:1: badly punctuated parameter list in `#define'

   

storage size of `XXX' isn't known

struct s st;

   

file:1: storage size of `st' isn't known

   

file:

   

file:

   

file:

   

file:

   

반응형

'Language > C' 카테고리의 다른 글

readv 함수 예제  (8) 2012.07.30
poll 함수 예제  (8) 2012.07.26
select 함수 예제  (8) 2012.07.23
Unix Domain Socket 예제  (6) 2012.07.23
semget. semop, semctl 함수 예제  (12) 2012.07.17

[다중 입출력 함수 select]

I/O 처리하는 경우 non-blocking 으로 여러개의 file descriptor를 체크하면서

읽어들일 데이터가 어떤 상태인지 확인하다가, 어떤 변화가 생기면

file descriptor를 리턴하게 된다.

만일 아무런 변화가 없다면 block 상태에 걸려버리는데

이는 timeout을 지정해서 빠져나올 수 있게 한다.

이 기능을 가지고 sleep대신 select를 사용할 수도 있다.

 

개인적으로 이해가 잘 안되서 이래저래 좀 자세히 테스트 해봤다.

 

       int select(int nfds, fd_set *readfds, fd_set *writefds,
                  fd_set *exceptfds, struct timeval *timeout);

 

내용출처 : http://mintnlatte.tistory.com/313

- nfds : 검사 대상이 되는 fd 범위로 세개의 집합(readfds/writefds/exceptfds)중 가장 큰 파일 디스크립터 값에 1을 더해서 전달하는 매개변수

- readfds : 시스템에 의해 즉시 입력이 가능한지 확인(읽기가 block되지 않았는지 검사하기 위한 리스트/ EOF 발생 검사)

- writefds : 시스템에 의해 즉시 출력이 가능한지 확인(쓰기가 block되지 않았는지 검사하기 위한 리스트)

- exceptfds : 예외가 있는지 검사하기 위한 리스트

- timeout : select가 반환하기 전에 블럭킹될 수 있는 시간의 제한 값 (0은 즉시반환 / NULL은 무한 block)

 

 ○ 리턴값

  -1 : 오류발생 

   0 : 타임아웃

양수: 변화 발생 파일 디스크립터 수

 

: FD_SET 구조체 / 변수 조작하는데 사용되는 함수들

 

○ FD_SET 구조체

 

 typedef struct fd_set {

    u_int          fd_count;

    SOCKET    fd_array[FD_SETSIZE];

 } fd_set;

- fd_count : 설정하는 파일 디스크립터의 번호

- fd_array : 설정된 파일 디스크립터의 배열

* fd_set은 0과 1로 저장되는 비트들의 배열이다.

 

○ FD_SET 변수 조작 함수

  - FD_SETFD_ZERO(fd_set *fdset) : fdset 포인터가 가리키는 변수의 모든 비트들을 0으로 초기화

  - FD_SET(int fd, fd_set *fdset) : fdset 포인터가 가리키는 변수에 fd로 전달되는 파일 디스크립터의 정보 설정(1로 설정)

  - FD_CLR(int fd, fd_set *fdset) : fdset 포인터가 가리키는 변수에 fd로 전달되는 파일 디스크립터의 정보를 삭제(0으로 설정)

  - FD_ISSET(int fd, fd_set *fdset) : fdset 포인터가 가리키는 변수가 fd로 전달되는 파일 디스크립터의 정보를 지니는지 확인

 

○ timeout 구조체

 

 

 struct timeval {

    long    tv_sec;

    long    tv_usec;

 }

-  tv_sec : 초 단위 설정 변수

- tv_usec : 마이크로 초 단위 설정 변수

 

 

 동작하는 방식

  FD_SET 변수에 변화가 생긴 파일 디스크립터는 1로 세팅, 변화가 없는 파일 디스크립터는 0으로 세팅한다.

 

 

- select 함수 호출 전 관찰 대상으로 fd0 과 fd3 이 설정되어 있다.

- select 함수 호출 후 fd3만 1로 설정되어있다.

=> fd3에 변화가 생겼음을 확인 & 해당 파일 디스크립터와 데이터 통신을 진행한다.

 

다음은 간단한 server/client를 구현했다. 그냥 echo 서버인데 서버쪽에서 여러개의

클라이언트를 그냥 받아들인다.

이걸 기본으로 하면 다른 것도 금방 짜겠다..

소스코드라인도 좀 기네;;;

 

==================================

 

서버측 소스코드
#include "sys/socket.h"
#include "sys/time.h"
#include "sys/types.h"
#include "sys/stat.h"
#include 
#include 
#include 
#include 
#include "netinet/in.h"
#include "arpa/inet.h"

#define FD_MAX_SIZE 1024

int main(int argc, char **argv)
{
    int server_sockfd, client_sockfd, sockfd;
    int state, client_len;
    int pid;
    int i, max_client, maxfd;
    int client[FD_MAX_SIZE];

    FILE *fp;
    struct sockaddr_in clientaddr, serveraddr;
    struct timeval tv;
    fd_set readfds, otherfds, allfds;

    int current_cli_num;
    char buf[255];
    char line[255];

    memset(line, 0x00, 255);
    state = 0;
    current_cli_num = 3;

    if ((server_sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        perror("socket error : ");
        exit(0);
    }

    memset(&serveraddr, 0x00, sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
    serveraddr.sin_port = htons(9000);

    state = bind(server_sockfd, (struct sockaddr *)&serveraddr,
            sizeof(serveraddr));
    if (state == -1) {
        perror("bind error : ");
        exit(0);
    }

    state = listen(server_sockfd, 5);
    if (state == -1) {
        perror("listen error : ");
        exit(0);
    }

    client_sockfd = server_sockfd;

    max_client = -1;
    maxfd = server_sockfd;

   for (i = 0; i < FD_MAX_SIZE; i++) {
        client[i] = -1;
    }

    FD_ZERO(&readfds);
    FD_SET(server_sockfd, &readfds);

    printf("\nTCP Server Waiting ...");
    fflush(stdout);

    while(1)
    {
        allfds = readfds;
        state = select(maxfd + 1 , &allfds, NULL, NULL, NULL);

        if (FD_ISSET(server_sockfd, &allfds)) {
            client_len = sizeof(clientaddr);
            client_sockfd = accept(server_sockfd,
                    (struct sockaddr *)&clientaddr, &client_len);
            printf("\nconnection from (%s , %d)",
                    inet_ntoa(clientaddr.sin_addr),ntohs(clientaddr.sin_port));

            for (i = 0; i < FD_MAX_SIZE; i++)
            {
                if (client[i] < 0) {
                    client[i] = client_sockfd;
                    printf("\nclientNUM=%d\nclientFD=%d\n", i+1, client_sockfd);
                    break;
                }
            }

            printf("accept [%d]\n", client_sockfd);
            printf("===================================\n");
            if (i == FD_MAX_SIZE) {
                perror("too many clients\n");
            }
            FD_SET(client_sockfd,&readfds);

            if (client_sockfd > maxfd)
                maxfd = client_sockfd;

            if (i > max_client)
                max_client = i;

            if (--state <= 0)
                continue;

        }
        for (i = 0; i <= max_client; i++)
        {
            if ((sockfd = client[i]) < 0) {
                continue;
            }

            if (FD_ISSET(sockfd, &allfds))
            {
                memset(buf, 0x00, 255);

                if (read(sockfd, buf, 255) <= 0) {
                    close(sockfd);
                    perror("Close sockfd : ");
                    FD_CLR(sockfd, &readfds);
                    client[i] = -1;
                }
                printf("[%d]RECV %s\n", sockfd, buf);
                write(sockfd, buf, 255);

                if (--state <= 0)
                    break;
            }
        }
    }
}
클라이언트 측 소스코드
#include "sys/socket.h"
#include "sys/types.h"
#include "netinet/in.h"
#include 
#include 
#include 
#include 
#include 
#include 

int main()
{
    int sock, bytes_recieved;
    char send_data[1024],recv_data[1024];
    struct hostent *host;
    struct sockaddr_in server_addr;

    host = gethostbyname("127.0.0.1");

    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
        perror("Socket");
        exit(1);
    }

    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(9000);
    server_addr.sin_addr = *((struct in_addr *)host->h_addr);
    memset(&(server_addr.sin_zero), 0x00, 8);

    if (connect(sock, (struct sockaddr *)&server_addr,
                sizeof(struct sockaddr)) == -1) {
        perror("Connect");
        exit(1);
    }

    while(1) {
        printf("\nSEND : ");
        fgets(send_data, sizeof(send_data), stdin);

        if (strcmp(send_data , "q") != 0 && strcmp(send_data , "Q") != 0)
            send(sock,send_data,strlen(send_data), 0);

        else {
            send(sock,send_data,strlen(send_data), 0);
            close(sock);
            break;
        }
        bytes_recieved=recv(sock,recv_data,1024,0);
        recv_data[bytes_recieved] = '\0';

        if (strcmp(recv_data , "q") == 0 || strcmp(recv_data , "Q") == 0) {
            close(sock);
            break;
        }
        else
            printf("\nRECV = %s\n " , recv_data);
    }
    return 0;
}
서버측의 결과 화면
TCP Server Waiting ...
connection from (127.0.0.1 , 53672)
clientNUM=1
clientFD=4
accept [4]
===================================

connection from (127.0.0.1 , 53681)
clientNUM=2
clientFD=5
accept [5]
===================================
[4]RECV nnnnnn

[5]RECV aaaaaa
클라이언트 측의 결과 화면
./aa_client

SEND : nnnnnn

RECV = nnnnnn

 

 

 

==================================

 

 

테스트하고 구현하는 건 자유인데 요러고 나니 아주쬐금 이해가 된다.

 

반응형

'Language > C' 카테고리의 다른 글

poll 함수 예제  (8) 2012.07.26
GCC 컴파일러 에러 메세지 리스트(Error Message List)  (6) 2012.07.24
Unix Domain Socket 예제  (6) 2012.07.23
semget. semop, semctl 함수 예제  (12) 2012.07.17
mmap / munmap 함수 예제  (10) 2012.07.17

내부 프로세스끼리 TCP 또는 UDP 프로토콜을 이용해서 통신하도록

도와주는 소켓이다. 아래의 예제를 보면 이 앞의 다른 IPC 통신과는 달리

특정 함수 API가 제공되지는 않는다. 기존의 TCP/IP 통신하는 소스코드와 거의 동일함.

 

 

================================================

 

서버측 소스 코드
#include "sys/types.h"
#include "sys/stat.h"
#include "sys/socket.h"
#include "sys/un.h"
#include 
#include 
#include 
#include 

#define MAXLINE 1024 

int main(int argc, char **argv)
{
    int server_sockfd, client_sockfd;
    int state, client_len;
    pid_t pid;

    FILE *fp;
    struct sockaddr_un clientaddr, serveraddr;

    char buf[MAXLINE]; 

    if (argc != 2) {
        printf("Usage : %s [socket file name]\n", argv[0]);
        exit(0);
    }

    if (access(argv[1], F_OK) == 0) {
        unlink(argv[1]);
    }

     client_len = sizeof(clientaddr);
     if ((server_sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
         perror("socket error : ");
         exit(0);
     }
     bzero(&serveraddr, sizeof(serveraddr));
     serveraddr.sun_family = AF_UNIX;
     strcpy(serveraddr.sun_path, argv[1]);

     state = bind(server_sockfd , (struct sockaddr *)&serveraddr,
             sizeof(serveraddr));
     if (state == -1) {
         perror("bind error : ");
         exit(0);
     }

     state = listen(server_sockfd, 5);
     if (state == -1) {
         perror("listen error : ");
         exit(0);
     }
     while(1)
     {
         client_sockfd = accept(server_sockfd, (struct sockaddr *)&clientaddr,
                 &client_len);
         pid = fork();
         if (pid == 0)
         {
             if (client_sockfd == -1) {
                 perror("Accept error : ");
                 exit(0);
             }

             while(1)
             {
                 memset(buf, 0x00, MAXLINE);
                 if (read(client_sockfd, buf, MAXLINE) <= 0) {
                     close(client_sockfd);
                     exit(0);
                 }
                 printf("RECV-> %s\n", buf);
                 write(client_sockfd, buf, strlen(buf));
             }
         }
     }
     close(client_sockfd);
}
클라이언트 측 소스코드
#include 
#include "sys/un.h"
#include 
#include 
#include 

#define MAXLINE 1024 


int main(int argc, char **argv)
{

    int client_len;
    int client_sockfd;

    FILE *fp_in;
    char buf_in[MAXLINE]; 
    char buf_get[MAXLINE]; 

    struct sockaddr_un clientaddr;

    if (argc != 2) {
        printf("Usage : %s [file_name]\n", argv[0]);
        exit(0);
    }

    client_sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
    if (client_sockfd == -1) {
        perror("error : ");
        exit(0);
    }

    bzero(&clientaddr, sizeof(clientaddr));
    clientaddr.sun_family = AF_UNIX;
    strcpy(clientaddr.sun_path, argv[1]);
    client_len = sizeof(clientaddr);

    if (connect(client_sockfd, (struct sockaddr *)&clientaddr, client_len) < 0)
    {
        perror("Connect error: ");
        exit(0);
    }
    while(1)
    {
        memset(buf_in, 0x00, MAXLINE); 
        memset(buf_get, 0x00, MAXLINE); 
        printf("> "); 
        fgets(buf_in, MAXLINE, stdin);
        write(client_sockfd, buf_in, strlen(buf_in));
        read(client_sockfd, buf_get, MAXLINE);
        printf("-> %s", buf_get);
    }

    close(client_sockfd);
    exit(0);
}
서버측 결과화면
RECV-> opipoipoikl

RECV-> 1

클라이언트측 결과화면
INPUT-> opipoipoikl
RECV-> opipoipoikl
INPUT-> 1
RECV-> 1

================================================

 

 

테스트하는 경우 %[실행파일명] [통신에 사용할 파일명]

저 파일을 설정해주고 사용하는 것만

다르고 나머지는 기본 TCP/IP와 동일하다.

 

다시 보니 이해가 좀 되네..

반응형

'Language > C' 카테고리의 다른 글

GCC 컴파일러 에러 메세지 리스트(Error Message List)  (6) 2012.07.24
select 함수 예제  (8) 2012.07.23
semget. semop, semctl 함수 예제  (12) 2012.07.17
mmap / munmap 함수 예제  (10) 2012.07.17
shmget/ shmat 함수 예제  (6) 2012.07.13

소스코드를 블로그에 삽입하기엔

기가 막히게 좋은것 같다.

 

5단계 만으로도 충분하다. 빨간글씨만 잘봐도 이해가 금방될것인데,

의문점은 댓글을 남겨 주시면 답변드리겠습니다.

mediawiki에 적용하는것 보다 훨씬 쉽네요.

 

 

다른 블로그에도 많은 내용들이 있기에 간단하게 적용하는 순서만 나열한다.

 

1. 다운 받는다.

http://alexgorbatchev.com/SyntaxHighlighter/download/

 

이 웹페이지 맨윗줄에 Click here to download라고 있다.

 

2. 받은 파일 압축 풀어둔다.

 

3. 티스토리 'Admin' - '꾸미기' 'html/css 편집' 모드에 가서  파일 업로드 누른다. 그리고 올린다.

 

[scripts]안의 모든 *.js 파일들 과 [styles] 폴더안의 모든 *.css 파일들을 업로드 하면 됨.

 

4. HTML/CSS에서 skin.html 수정해야한다.

</body>, </html> 사이에다가 이거 가져다 붙이면된다.

2012년 7월에 작성해놓고 2016년 2월에 다시 따라서 해봤는데 잘됩니다. 오예

 

</body>

<script type="text/javascript" src="./images/shCore.js"></script>
<script type="text/javascript" src="./images/shLegacy.js"></script>
<script type="text/javascript" src="./images/shBrushBash.js"></script>
<script type="text/javascript" src="./images/shBrushCpp.js"></script>
<script type="text/javascript" src="./images/shBrushCSharp.js"></script>
<script type="text/javascript" src="./images/shBrushCss.js"></script>
<script type="text/javascript" src="./images/shBrushDelphi.js"></script>
<script type="text/javascript" src="./images/shBrushDiff.js"></script>
<script type="text/javascript" src="./images/shBrushGroovy.js"></script>
<script type="text/javascript" src="./images/shBrushJava.js"></script>
<script type="text/javascript" src="./images/shBrushJScript.js"></script>
<script type="text/javascript" src="./images/shBrushPhp.js"></script>
<script type="text/javascript" src="./images/shBrushPython.js"></script>
<script type="text/javascript" src="./images/shBrushSql.js"></script>
<script type="text/javascript" src="./images/shBrushXml.js"></script>
<link type="text/css" rel="stylesheet" href="./images/shCore.css">
<link type="text/css" rel="stylesheet" href="./images/shThemeEmacs.css">
<script type="text/javascript">
SyntaxHighlighter.all();
</script>

 </html>


* shThemeEmac.css는 내가 저 스타일이 좋아서 쓴것이므로 아무거나 좋은대로 바꿔쓰면 된다. [styles]폴더안에 있는 파일중에 업로드 시킨건 아무거나 다 될것임.

테마 종류 관련 정보는 여기 가면 완벽하게 나와있음

http://alexgorbatchev.com/SyntaxHighlighter/manual/themes/

 

5. 이제 글쓰기 모드로 가서 글을 쓴다.

 

 

저기 HTML 체크하고 나서

 

<pre class="brush:c;">

#include <stdio.h>

int main()

{

printf("HELLO WORLD\n"):

return 0;

}

</pre>

 

이런식으로 하면 끝난다.

브러쉬를 C로 설정했는데 다른게 필요하다면 다음의 링크를 참조해주시길..

http://alexgorbatchev.com/SyntaxHighlighter/manual/brushes/

반응형

+ Recent posts