레퍼런스 쪽 질문입니다.

nayana의 이미지

소스는 다음과 같습니다.

#include <iostream>

using namespace std;

int max( int a, int b )
{
	return ( a > b ) ? a : b;
}

int main( void )
{
	int a = 123, b = 456;
	int ( &f )( int, int ) = max;

	cout << max( a, b ) << ' ' << f( a, b ) << endl;
	cout << &max << ' ' << &f << endl;

	return 0;
}

g++ 컴파일을 해보니 수많은 에러가 떨어집니다.
그래서 vc++ 에서 컴파일 해보니...무난히 컴파일이 되었습니다.
그런데...max 의 주소와 f 주소가 같아야하는게 아닌가요...
레퍼런스 f에 max함수는 동일한 영역을 공유하는걸로 알고 있는데..?
다음은 윈도우에서 한결과 입니다.
456 456
00401212 0012FF74

그리고 리눅스에서는 왜 수많은 에러가 떨어지는 이유가 몬가요?
redbaron의 이미지

nayana wrote:

456 456
00401212 0012FF74


redbaron@oper redbaron$ g++ test.cpp
redbaron@oper redbaron$ ./a.out
456 456
1 1

라고 나오는군요. ㅡ_ㅡㅋ FreeBSD에.. g++은.. 2.95.4

nayana의 이미지

저는 레드핫 9.0, gcc 버젼은 3.2.2 입니다.
다음은 오류코드 입니다.

funcref.cpp: In function `int main()':
funcref.cpp:16: no match for `std::ostream& << <unknown type>' operator
/usr/include/c++/3.2.2/bits/ostream.tcc:55: candidates are:
   std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT,
   _Traits>::operator<<(std::basic_ostream<_CharT,
   _Traits>&(*)(std::basic_ostream<_CharT, _Traits>&)) [with _CharT = char,
   _Traits = std::char_traits<char>]
/usr/include/c++/3.2.2/bits/ostream.tcc:77:
   std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT,
   _Traits>::operator<<(std::basic_ios<_CharT,
   _Traits>&(*)(std::basic_ios<_CharT, _Traits>&)) [with _CharT = char, _Traits
   = std::char_traits<char>]
/usr/include/c++/3.2.2/bits/ostream.tcc:99:
   std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT,
   _Traits>::operator<<(std::ios_base&(*)(std::ios_base&)) [with _CharT = char,
   _Traits = std::char_traits<char>]
/usr/include/c++/3.2.2/bits/ostream.tcc:171:
   std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT,
   _Traits>::operator<<(long int) [with _CharT = char, _Traits =
   std::char_traits<char>]
/usr/include/c++/3.2.2/bits/ostream.tcc:208:
   std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT,
   _Traits>::operator<<(long unsigned int) [with _CharT = char, _Traits =
   std::char_traits<char>]
/usr/include/c++/3.2.2/bits/ostream.tcc:146:
   std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT,
   _Traits>::operator<<(bool) [with _CharT = char, _Traits =
   std::char_traits<char>]
/usr/include/c++/3.2.2/ostream:104:                 std::basic_ostream<_CharT,
   _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(short int) [with
   _CharT = char, _Traits = std::char_traits<char>]
/usr/include/c++/3.2.2/ostream:115:                 std::basic_ostream<_CharT,
   _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(short unsigned
   int) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/include/c++/3.2.2/ostream:119:                 std::basic_ostream<_CharT,
   _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(int) [with _CharT
   = char, _Traits = std::char_traits<char>]
/usr/include/c++/3.2.2/ostream:130:                 std::basic_ostream<_CharT,
   _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(unsigned int)
   [with _CharT = char, _Traits = std::char_traits<char>]
/usr/include/c++/3.2.2/bits/ostream.tcc:234:
   std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT,
   _Traits>::operator<<(long long int) [with _CharT = char, _Traits =
   std::char_traits<char>]
/usr/include/c++/3.2.2/bits/ostream.tcc:272:
   std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT,
   _Traits>::operator<<(long long unsigned int) [with _CharT = char, _Traits =
   std::char_traits<char>]
/usr/include/c++/3.2.2/bits/ostream.tcc:298:
   std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT,
   _Traits>::operator<<(double) [with _CharT = char, _Traits =
   std::char_traits<char>]
/usr/include/c++/3.2.2/ostream:145:                 std::basic_ostream<_CharT,
   _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(float) [with
   _CharT = char, _Traits = std::char_traits<char>]
/usr/include/c++/3.2.2/bits/ostream.tcc:323:
   std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT,
_Traits>::operator<<(long double) [with _CharT = char, _Traits =
   std::char_traits<char>]
/usr/include/c++/3.2.2/bits/ostream.tcc:348:
   std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT,
   _Traits>::operator<<(const void*) [with _CharT = char, _Traits =
   std::char_traits<char>]
/usr/include/c++/3.2.2/bits/ostream.tcc:120:
   std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT,
   _Traits>::operator<<(std::basic_streambuf<_CharT, _Traits>*) [with _CharT =
   char, _Traits = std::char_traits<char>]
/usr/include/c++/3.2.2/bits/ostream.tcc:464:
   std::basic_ostream<_CharT, _Traits>&
   std::operator<<(std::basic_ostream<_CharT, _Traits>&, _CharT) [with _CharT =
   char, _Traits = std::char_traits<char>]
/usr/include/c++/3.2.2/ostream:211:                 std::basic_ostream<_CharT,
   _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&, char) [with
   _CharT = char, _Traits = std::char_traits<char>]
/usr/include/c++/3.2.2/bits/ostream.tcc:500:
   std::basic_ostream<char, _Traits>& std::operator<<(std::basic_ostream<char,
   _Traits>&, char) [with _Traits = std::char_traits<char>]
/usr/include/c++/3.2.2/ostream:222:                 std::basic_ostream<char,
   _Traits>& std::operator<<(std::basic_ostream<char, _Traits>&, signed char)
   [with _Traits = std::char_traits<char>]
/usr/include/c++/3.2.2/ostream:227:                 std::basic_ostream<char,
   _Traits>& std::operator<<(std::basic_ostream<char, _Traits>&, unsigned char)
   [with _Traits = std::char_traits<char>]
/usr/include/c++/3.2.2/bits/ostream.tcc:535:
   std::basic_ostream<_CharT, _Traits>&
   std::operator<<(std::basic_ostream<_CharT, _Traits>&, const _CharT*) [with
   _CharT = char, _Traits = std::char_traits<char>]
/usr/include/c++/3.2.2/bits/ostream.tcc:572:
   std::basic_ostream<_CharT, _Traits>&
   std::operator<<(std::basic_ostream<_CharT, _Traits>&, const char*) [with
   _CharT = char, _Traits = std::char_traits<char>]
/usr/include/c++/3.2.2/bits/ostream.tcc:622:
   std::basic_ostream<char, _Traits>& std::operator<<(std::basic_ostream<char,
   _Traits>&, const char*) [with _Traits = std::char_traits<char>]
/usr/include/c++/3.2.2/ostream:246:                 std::basic_ostream<char,
   _Traits>& std::operator<<(std::basic_ostream<char, _Traits>&, const signed
   char*) [with _Traits = std::char_traits<char>]
/usr/include/c++/3.2.2/ostream:251:                 std::basic_ostream<char,
   _Traits>& std::operator<<(std::basic_ostream<char, _Traits>&, const unsigned
   char*) [with _Traits = std::char_traits<char>]
singlet의 이미지

std::max() 와의 이름 충돌일 겁니다. max() 함수의 이름을 바꿔보시압. (또는 namespace 를 명시하여 ::max 라고 적어줘도 될 겁니다.) 또한, ostream 에 함수 포인터를 받아먹는 << 연산자까지 있다는 보장은 (아마도) 없을 겁니다. 주소를 알아보고 싶으시다면 void* 형으로 캐스트하시길. 이렇게 해 주면 g++ 3.3.2 에서는 제대로 답 나옵니다.

456 456
0x8048774 0x8048774

그건 그렇고, 에러가 떨어진다는 막연한 질문 대신 어떤 에러가 떨어지는지 잘 살펴보시고 정확히 올려놓을 수 있도록 노력해보시기 바랍니다. 답변자가 답하기 어려운 건 둘째치고라도, 살펴보다 보면 답이 스스로 나옵니다. 자세히 살펴보셨다면 아마도 수많은 에러 메시지가 떨어지지만 사실 진짜 에러는 다음의 단 한 개 뿐이었다는 것을 아실 수 있었을 겁니다. (g++ 3.3.2 의 에러 메시지입니다.)
test.cc:16: error: no match for 'operator<<' in 'std::cout << &std::max'
그리고 그 뒤를 줄줄줄 이어 쏟아지는 메시지들은 다음과 같은 것들이었을 것입니다. (가독성을 위해 이름을 줄이고 컬럼을 맞췄습니다.)
.../bits/ostream.tcc:63:  error: candidates are:
                                 ostream& ostream::operator<<(ostream&(*)(ostream&))
.../bits/ostream.tcc:85:  error: ostream& ostream::operator<<(ios&(*)(ios&))
.../bits/ostream.tcc:107: error: ostream& ostream::operator<<(ios_base&(*)(ios_base&))
.../bits/ostream.tcc:179: error: ostream& ostream::operator<<(long int)
.../bits/ostream.tcc:216: error: ostream& ostream::operator<<(long unsigned int)
.../bits/ostream.tcc:154: error: ostream& ostream::operator<<(bool)
.../ostream:178:          error: ostream& ostream::operator<<(short int)
.../ostream:189:          error: ostream& ostream::operator<<(short unsigned int)
.../ostream:193:          error: ostream& ostream::operator<<(int)
.../ostream:204:          error: ostream& ostream::operator<<(unsigned int)
.../bits/ostream.tcc:242: error: ostream& ostream::operator<<(long long int)
.../bits/ostream.tcc:280: error: ostream& ostream::operator<<(long long unsigned int)
.../bits/ostream.tcc:306: error: ostream& ostream::operator<<(double)
.../ostream:219:          error: ostream& ostream::operator<<(float)
.../bits/ostream.tcc:331: error: ostream& ostream::operator<<(long double)
.../bits/ostream.tcc:356: error: ostream& ostream::operator<<(const void*)
.../bits/ostream.tcc:128: error: ostream& ostream::operator<<(streambuf*)
.../bits/ostream.tcc:472: error: ostream& operator<<(ostream&, _CharT)
.../ostream:436:          error: ostream& operator<<(ostream&, char)
.../bits/ostream.tcc:508: error: ostream& operator<<(ostream&, char)
.../ostream:447:          error: ostream& operator<<(ostream&, signed char)
.../ostream:452:          error: ostream& operator<<(ostream&, unsigned char)
.../bits/ostream.tcc:543: error: ostream& operator<<(ostream&, const _CharT*)
.../bits/ostream.tcc:580: error: ostream& operator<<(ostream&, const char*)
.../bits/ostream.tcc:630: error: ostream& operator<<(ostream&, const char*)
.../ostream:486:          error: ostream& operator<<(ostream&, const signed char*)
.../ostream:491:          error: ostream& operator<<(ostream&, const unsigned char*)
오버로드된 << 연산자들의 나열로서 위 에러 메시지에 대한 부가적인 정보에 불과합니다. 즉 문제는 "함수 템플릿인 std::max() 를 받아먹는 << 연산자를 찾을 수 없었다" 로 요약됩니다. 그리고 이것은 처음에 적은 대로 std::max() 와 ::max() 와의 이름 충돌 때문인 거고요.

p.s. 대강 replace 하다보니 위 에러 메시지에 약간 이상한 부분이 남아 있군요. 적당히 ^^; 읽어주시기 바랍니다.

redbaron의 이미지

#include <iostream>

using namespace std;

int maxim( int a, int b )
{
   return ( a > b ) ? a : b;
}

int main( void )
{
   int a = 123, b = 456;
   int ( &f )( int, int ) = maxim;

   cout << maxim( a, b ) << ' ' << f( a, b ) << endl;
   cout << (void*) &maxim << ' ' << (void*) &f << endl;

   return 0;
}

함수 이름은 모회사의 제품과 약간 상관이 있습니다. ㅋ

redbaron@haessal:~$ g++ test.cpp
redbaron@haessal:~$ ./a.out
456 456
0x8048794 0x8048794

원하시는 결과가 맞는지요?

댓글 달기

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