gcc 옵션 중에-fno-strict-aliasing 란 게 뭔가요?

kyagrd의 이미지

커널 컴파일하는 분들이 gcc 최적화 옵션을 줄 때 이것도 꼭 같이 주라고 하던데요, 이게 뭐하는 거고 왜 줘야 하는 건가요?

cmoh1110의 이미지

man gcc
....
-fstrict-aliasing
Allows the compiler to assume the strictest aliasing rules applicable to the language being
compiled. For C (and C++), this activates optimizations based on the type of expressions. In
particular, an object of one type is assumed never to reside at the same address as an object
of a different type, unless the types are almost the same. For example, an "unsigned int" can
alias an "int", but not a "void*" or a "double". A character type may alias any other type.

Pay special attention to code like this:

union a_union {
int i;
double d;
};

int f() {
a_union t;
t.d = 3.0;
return t.i;
}

The practice of reading from a different union member than the one most recently written to
(called ‘‘type-punning’’) is common. Even with -fstrict-aliasing, type-punning is allowed,
provided the memory is accessed through the union type. So, the code above will work as
expected. However, this code might not:

int f() {
a_union t;
int* ip;
t.d = 3.0;
ip = &t.i;
return *ip;
}

Every language that wishes to perform language-specific alias analysis should define a function
that computes, given an "tree" node, an alias set for the node. Nodes in different alias sets
are not allowed to alias. For an example, see the C front-end function "c_get_alias_set".

Enabled at levels -O2, -O3, -Os.
....
---------------------

전웅의 이미지

C 언어 표준에 anti-aliasing rule (혹은 lvalue access rule) 이라는
규칙이 있습니다. 이 규칙은 일반적인 프로그램에서 잘못된 구조가 될
가능성이 큰 프로그램에 대해 컴파일러가 마음 놓고 "type 에 기반한
최적화"를 가할 수 있도록 허락해주는 규칙으로, 다음과 같은 예로
대강 설명할 수 있습니다.

void func(int *a, double *b)
{
    *b = 3.0;
    *a = 1;
    foo(*b);
}

이때 foo(*b); 를 foo(3.0); 으로 최적화가 가능할까요? 이는 아래와
같은 함수 호출이 올바른 것이냐 그렇지 않느냐에 따라 달라집니다.

double c;
func((int *)&c, &c);

만약, 이와 같은 구조가 올바른 구조로 인정된다면 위에서 말한
컴파일러의 최적화는 허용될 수 없으며, 그렇지 않다면 자유롭게
최적화를 수행할 수 있게 됩니다.

C 표준의 입장은 double 형 대상체와 int 형 대상체를 aliasing 해서
사용하는 것이 이식성도 없을 뿐더러 잘못된 프로그램으로 본다는
것입니다. 따라서 컴파일러는 func() 를 호출하는 문맥을 살펴볼 필요도
없이 오로지 지역적인 type 정보에만 의존해 앞서 말씀드린 것같은
최적화를 수행할 수 있습니다.

보통의 C 프로그램은 특정 환경에 의존하면서 포인터를 사용해 다양한
type punnig 을 수행하기 때문에 위와 같은 표준이 허락해준 "면허"가
있어도 실제 그러한 최적화를 "항상" 수행하는 컴파일러는 없습니다.
대부분의 경우 그와 같은 최적화를 켜고, 끌 수 있는 옵션을 제공해
(비록 표준 관점에서는 잘못된 구조이지만) 그와 같은 aliasing 을 필요로
하는 프로그램이 "적법한" 최적화로 인해 오작동할 걱정 없이 컴파일할 수
있게 해주는 것입니다.

커널을 컴파일 할 때 -fno-... 옵션을 주어야 한다는 이야기는 커널이
바로 그와 같은 (표준 관점에서 불법적인) aliasing 에 의존한다는 이야기
입니다. 따라서 anti-aliasing rule 에 기반해 최적화를 하도록 옵션을
잘못 줄 경우 커널 이곳 저곳에서 의도하지 않은 결과가 생겨 오작동이
가능함을 뜻합니다.

man page 에 나온 union 과 관련된 내용은 다소 복잡한 이야기에 해당
됩니다. union 은 그 자체가 aliasing 을 위해 존재합니다 - 원하든
그렇지 않든 union 의 멤버는 모두 aliasing 됩니다. 따라서 컴파일러
입장에서 union 을 통한 접근이 명백하게 보이는 경우에는 이를 의도적인
aliasing 으로 인정해 결과를 망칠 수 있는 최적화를 적용하지 않는다는
것입니다. 실제로 모 컴파일러의 경우 특정 type 이 union 멤버로
나왔다는 사실만으로 해당 type 에 대한 anti-aliasing rule 에 기반한
지역적인 최적화를 모두 끄기도 합니다.

하지만, anti-aliasing rule 를 사용한 union 의 최적화 문제의 경우
아직도 표준에서 제대로 정리가 되지 않은 상태입니다. C99 이후 정리가
되었다고 생각했으나 실제로는 그렇지 않음이 밝혀졌고 (이 Defect
Report 를 제가 제기했습니다! ^^V) 현재 다른 다양한 문제(예를 들면
동적으로 할당된 메모리 공간에 대한 anti-aliasing rule 적용)와 함께
해결하기 까다로운 문제로 남아 있습니다. 따라서 각 컴파일러는 관례에
의존하면서 가능한 프로그램을 깨뜨리지 않는 방향으로 최적화 구현을
하고 있습니다.

--
Jun, Woong (woong at icu.ac.kr)
Web: http://www.woong.org (서버 공사중)

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

댓글 달기

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