씨언어 ... warning: concatenation of string

bw001730의 이미지

#define debug "["__PRETTY_FUNCTION__ "]"
제가 디버깅용으로 이런 코드를 작성했습니다.

에러는 아니지만..경고문이 발생하는데요
음..
warning: concatenation of string ... 어쩌구 저쩌구..

동작은 되걸랑요
아마도 문자열연결을 하는 과정에서 발생하는 경고문인것 같은데
어떻게 해결할 수 있는지 방법좀 알려주시면 감사드리겠습니다.

cinsk의 이미지

어쩌구 저쩌구가 뭔지 알려주셔야죠.

bw001730의 이미지

답변을 올려주셔서 감사합니다.

저는 아래와 같이 코드를 작성했구요
#define debug "["__PRETTY_FUNCTION__ "]"

에러메시지는 아래와 같이 나옵니다.
warning: concatenation of string literals with __FUNCTION__ is deprecated

__FUNCTION__ 매크로를 사용하지 않고 __PRETTY_FUNCTION__ 을
사용했는데도..
__FUNCTION__ 이 deprecated 됬다는 메시지가 나왔습니다.

좋은 사이트 알려주셔서 감사드립니다. ^__^

cinsk의 이미지

__FUNCTION__은 c preprocessor에서 자동으로 처리해 주는 매크로가 아닙니다. 이 것은 현재 함수 이름을 나타내는 문자열이 담겨있는 배열이라고 생각하시면 됩니다.

물론 좀 더 자세히 말하면, __FUNCTION__은 gcc extension이고, C99에서는 __func__으로 정의하고 있는 predefined identifier이며, c preprocessor는 이 identifier에 대해 아는 바가 없습니다. 바로 이 점이 __FILE__, __LINE__과의 차이점입니다. 즉 __FUNCTION__이나 __func__은 macro name도 아니며, string literal이라고 할 수도 없습니다.

__FUNCTION__이 __func__와 동일하다고 생각하시면 됩니다 (사실은 약간 차이가 있지만). __func__에 대한 ISO C 표준 설명을 보면:

ISO C Standard wrote:
The identifier __func__ shall be implicitly declared by the translator as if, immediately following the opening brace of each function definition, the declaration

static const char __func__[] = "function-name"

appeared, where function-name is the name of the lexically-enclosing function.

즉 문자 배열로 생각할 수 있기 때문에 string constant concatenation이 불가능합니다.

__FUNCTION__의 경우는 약간 다른데, 이는 "info cpp", "info gcc"를 실행해서 __FUNCTION__으로 검색해보시면 자세한 내용이 나오므로 생략하겠습니다.

전웅의 이미지

predefined macro 가 아닌 predefined identifier 인 __func__ 에 대해서는
아래도 참고하시기 바랍니다.

http://c-expert.uos.ac.kr/board/hclc_post_board/ScB.cgi?process=disp_data&datanum=647

원래 KLDP 에 썼던 글인데 어디 있는지 모르겠군요. --;

--
Jun, Woong (woong at gmail.com)
http://www.woong.org

bw001730의 이미지

몰랐던 사실을 많이 알게되었습니다.
그렇게 웹질을 해도 모르고 있는 좋은 사이트들이 무척많은것 같네요
알려주셔서 감사합니다.

어쨌든 아래의 경고메시지는.....
없앨수 없군요
concatenation of string literals with __FUNCTION__ is deprecated
에러가 아니라 경고라서 그냥 경고메시지 보면서 컴파일하여 사용합니다.

제가 원하는 것은 아래와 같은 것입니다.

#define myprefix __FILE__":"__FUNCTION__

// 아래는 안되더군요. __func__ 가 매크로 상수가 아닌 변수기 때문인듯.
// #define myprefix __FILE__":"__func__

....

main()
{
if( 에러)
printf("%s 이러저런 에러가 발생함" , myprefix);
.....
}

이렇게 하면 myprefix 에서 문자열을 결합했기때문에
경고메시지가 발생합니다.

하지만 저는 이게 편하기 때문에 경고메시지 보면서 그냥 사용하고
있습니다. 동작은 되더군요

혹시..아래의 경고메시지까지 없앨 좋은 방법없을까요?
warining: concatenation of string literals

관심가져주신분들에게 감사드립니다.

cinsk의 이미지

에러 메시지 출력 루틴이 필요했던 거군요. 진작 그렇게 말씀하시지요.

그럼 다음과 같이 만들어 보세요.

일단 err.h입니다:

#ifndef err_h
#define err_h

#include <stddef.h>

#ifdef __cplusplus
extern "C" {
#endif

extern void err_(const char *filename, unsigned long lineno, 
                 const char *funcname, int status, int code, 
                 const char *fmt, ...)
#ifdef __GNUC__
     __attribute__ ((format(printf, 6, 7)))
#endif /* __GNUC__ */
     ;

#ifdef __GNUC__
# define err(status, code, fmt...)	\
		err_(__FILE__, __LINE__, __FUNCTION__, \
		     status, code, fmt)

#elif defined(__STDC__)

# define err(status, code, ...)	\
		err_(__FILE__, __LINE__, __FUNCTION__, \
		     status, code, __VA_ARGS__)

#else
#error At least you should use ISO C complaint compiler or GCC.
#endif

#ifdef __cplusplus
}
#endif
#endif /* err_h */

그리고 err.c입니다:

#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "err.h"

void
err_(const char *filename, unsigned long lineno, const char *funcname,
     int status, int code, const char *fmt, ...)
{
  va_list argptr;

  fflush(stdout);
  fflush(stderr);               /* Normally, this has no effect. */

  fprintf(stderr, "%s:%lu:%s: ", filename, lineno, funcname);

  if (code)
    fprintf(stderr, "%s: ", strerror(code));

  va_start(argptr, fmt);
  vfprintf(stderr, fmt, argptr);
  va_end(argptr);

  fputc('\n', stderr);
  fflush(stderr);   /* As I said before, this might have no effect. */

  if (status)
    exit(status);
}

어떻게 쓰냐면 아래 예제를 참고하세요:

#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>

#include "err.h"

int
main(void)
{
  const char *filename = "this_is_not_real_file_name";

  int fd;
  fd = open(filename, O_RDONLY);
  err(0, errno, "cannot open %s", filename);

  /* If some critical error is encountered.. */
  err(1, 0, "critical error, cannot process ...");
  printf("This sentence will not be excuted.\n");
  return 0;
}

이 루틴은 header file (err.h)에 써 놓은 것처럼, ISO C 호환 컴파일러나 GCC에서만 동작합니다.

cinsk의 이미지

참고로 위 routine은 glibc error() 함수 소스를 훔쳐서 약간 고쳐봤습니다. ;^)

bw001730의 이미지

아...이런 방법도 있엇군요.
답변에 무척 만족합니다만..

만약에 이런 경우도 있을 것입니다.
함수에 진입하면서 trace_in()
함수를 빠져나가면서 trace_out()
스택을 trace_in/out 하는 매크로를 만들고 싶습니다.

함수를 진입할때마다. __FILE__":"__FUNCTION__를
기록해두었다가 또 진입하면 또 기록해두고 그러다 빠져나가면서
지우고...
근데 이 작업을 malloc()/free()하기는 귀찬고.
만약 __FILE__":"__FUNCTION__ 이 상수이면 따악 좋겠는데
포인터만 가리켰다가..포인터만 지우면 되니깐. 할당, free할 필요도 없고

그래서 __FUNCTION__ 이 문자열연결이 가능했으면 좋겠다는
생각이 드네요..

지금 멀티스레드에서 각 스레드별로 스택추적을 할려고 하다보니..
되기는 되는데..경고가 자꾸 떠서리..

암튼 답변은 감사합니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.