volatile void func(...) 함수의 컴파일 warning 에 대해서...

joobeom의 이미지

안녕하세요.

진정한 volatile 의 의미가 아닌것 같긴 하지만,,,
함수 자체를 컴파일 최적화 하지 않기 위해 volatile 키워드를
아래와 같이 가끔 사용했습니다.

그런데, void 함수에 volatile 를 붙히니 warning 이 나는군요.

특정 함수의 컴파일 최적화를 피하기 위해 volatile 를 붙히면 안되는요?

혹시 안된다면 다른 키워드라도 있는지...

아래는 테스트 소스 입니다.

#include <stdio.h>
volatile void print(void)
{
    printf("test ...\n");
}
int main()
{
    print();
    return 0;
}

prio의 이미지

아마도 워닝 메시지에 안내되었을테지만..

void 는 말 그대로 리턴 값이 없다는 뜻이므로 type qualifier에 의해 qualified 될 수 없습니다.

(될 필요가 없다고 하는 게 더 정확하겠네요.)

리턴 값이 의미 있는 데이터 형을 가져야 const 니 volatile 이니 하는 것을 지정할 수 있으니까요.

그런데 volatile 키워드를 붙이면 함수 전체에 대해 컴파일러 최적화를 하지 않는다는 것은 금시초문인데요.

(제가 과문한 탓일 수도 있지만요;; )

cppig1995의 이미지

volatile은 함수에 지정되는 게 아니라 반환값에 지정될 뿐입니다.
함수 전체를 최적화하지 않으시려면 컴파일러 옵션을 지정하셔야죠.

Real programmers /* don't */ comment their code.
If it was hard to write, it should be /* hard to */ read.

bootmeta의 이미지

개인적으로 완벽하게 동작하는지는 좀 의심스럽스니다만, gcc의 경우 function pure 속성이 가능합니다.

http://www.ohse.de/uwe/articles/gcc-attributes.html

pure
    Found in versions: 3.0-3.4 
    Introduced in version 2.96. (according to documentation) 
    Description:
 
         Many functions have no effects except the return value and their
         return value depends only on the parameters and/or global
         variables.  Such a function can be subject to common subexpression
         elimination and loop optimization just as an arithmetic operator
         would be.  These functions should be declared with the attribute
         `pure'.  For example,
 
              int square (int) __attribute__ ((pure));
 
         says that the hypothetical function `square' is safe to call fewer
         times than the program says.
 
         Some of common examples of pure functions are `strlen' or `memcmp'.
         Interesting non-pure functions are functions with infinite loops
         or those depending on volatile memory or other system resource,
         that may change between two consecutive calls (such as `feof' in a
         multithreading environment).
 
         The attribute `pure' is not implemented in GCC versions earlier
         than 2.96.


int square (int) __attribute__ ((pure));
int square (int) 
{
 ... 
}

형태 또는
 __attribute__ ((pure)) int square (int)
{
 ... 
}

c++의 경우 사용자 정의 class로 변수 선언시 volatile을 앞에 붙이면
member function은 volatile 인 경우만 접근 가능합니다.

http://www.memorycarrier.com/old_www/y2k2/volatile.html

class My {
public:
	void foo() volatile {};
	void bar() {};
	int i;
};
 
int main() 
{
    volatile My x;
    x.foo();       // ok
    int j = x.i;   // ok - i는 자동으로 volatile
    x.bar();       // error: passing ‘volatile My’ as ‘this’ argument of ‘void My::bar()’ discards qualifiers
}

ps)
변수에 대한 C volatile은 앞선 분들이 잘 설명해 주신듯
좀더 google 검색해보니 pure는 그 용도가 아닌듯 싶군요.(저도 안써봐서 ^^;)
도리어 pure hint를 보고 적극적인 optimizing 시도하려고 하는 것으로 보입니다.
더우기 volatile과는 직접적인 관계가 없는 것 같네요.
잘 아시는 분에게 pass
http://lwn.net/Articles/285332/

prio의 이미지

어차피 인용하신 글에 다 설명되어 있지만.. 간단한 예를 추가합니다.

int global_counter = 0;
 
int add(int x, int y) {
    global_counter++;
    return x + y;
}
 
int add_pure(int x, int y) {
    return x + y;
}
 
void foo() {
 
    /* ... */
 
    x = a + b;
    y = a + b + c;    /* the expression 'a + b' can be replaced by 'x' */
 
    /* ... */
}
 
void bar() {
    /* ... */
 
    x = add(a, b);
    y = add(a, b) + c;    /* the call to add() cannot be replaced by 'x' */
 
    /* ... */
}
 
void baz() {
    /* ... */
 
    x = add_pure(a, b);
    y = add_pure(a, b) + c;    /* replacing 'add_pure(a, b)' by 'x' does not affect the program behavior */
 
    /* ... */
}

joobeom의 이미지

답변 감사 드립니다.

그런데, 궁금한 것이 하나 더 있는데요.
아래와 같이 asm 키워드에 volatile 라고 붙히면 어떤 결과가 나오나요?

volatile 의 진정한 의미에서 본다면,
변수 선언시 register 가 아닌 memory 로 한다는 것인데,,,
의미 매칭이 잘 안되는 군요.
(개인적으로 asm 에 volatile 을 붙히면 컴파일러 마음대로 asm 을 해석 하지
말라고 알고 있음)

고수님들의 의견 부탁 드립니다.

    asm volatile(
        "   stsch   0(%3)\n"
        "   ipm %0\n"
        "   srl %0,28"
        : "=d" (ccode), "=m" (*addr)
        : "d" (reg1), "a" (addr)
        : "cc");

prio의 이미지

gcc의 inline assembler에서 volatile 키워드를 특별한 용도로 사용하는 것입니다.

inline assembly에서 volatile 키워드를 붙이면 컴파일러 최적화를 하지 않는 것은 맞습니다.

(고수는 아니지만 의견 붙입니다. 흐흐;; )

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.