[완료] Gcc4.4 AMD64 에서 void* 로 int 넘기기

coldfury의 이미지

pthread_create( &threads[i], NULL, &thread_main, (void*)i );

보통 thread를 만들 때 이렇게 만들고

void *thread_main( void *arg ){
int index = (int)arg;
...
}

이렇게 쓰는걸로 아는데요. 64비트에서 컴파일하니

error: cast from 'void*' to 'int' loses precision

이런 에러가 나더군요.

void*형 포인터의 크기가 int형보다 커서 그런 에러가 나는것 같은데요.

void *thread_main( void *arg ){
int index = (intptr_t)arg;
...
}

이렇게 해결했습니다.

그런데, 제가 생각한 문제의 원인이 맞는건지, 해결방법은 안전한건지 의견을 듣고 싶습니다.

nthroot의 이미지

< pthread_create( &threads[i], NULL, &thread_main, (void*)i );
> pthread_create( &threads[i], NULL, &thread_main, (void*)&i );
< int index = (int)arg;
> int index = *(int*)arg;

음 확인은 안해봤지만 이래야 할것 같네요.(64비트랑은 상관없는 내용입니다.)

------식은이 처------
길이 끝나는 저기엔 아무 것도 없어요. 희망이고 나발이고 아무 것도 없어.

unipro의 이미지

i 라는 값이 지역 변수라면, 쓰레드가 참조하는 시점에서 i 값이 스코프를 벗어났을 경우,
쓰레드에서 참조할 시점에서 다른 값으로 변경되었을 경우,
(게다가 질문자의 변수 이름으로 봐서는 반복문에서 사용하는 변수 같은데, 이 경우는 참조 시점에서 거의 변한다고 보여집니다.)
문제가 발생합니다.
----
내 블로그: http://unipro.tistory.com

내 블로그: http://unipro.tistory.com

kaeri17의 이미지

다른 방법으로는 long long으로 캐스팅 한 다음 다시 int로 하면 된다네요. void*경우는 주소값이기때문에 32비트값만 덜렁 남아버리면 심각해지기 떄문에 컴파일러에서 금지를 시켜 놓는다는 듯..

winner의 이미지

Ubuntu 10.04, gcc 4.4.3입니다.

void *arg = 0;
int i = (int)arg;

위 두줄을 시험해봤습니다.

제가 알기로 intptr_t는 64bit에서 일반적으로 long int 로 typedef 되니 자료형 크기는 여전히 차이가 날 것 같습니다.
그런데 gcc에서는 정수형끼리 자료형크기가 다른 것은 경고를 내지 않는군요. -Wall에 -pedantic 도 줘봤지만 역시 안나네요.

제 생각에 우선적으로 void *에서 intptr_t로 변환될 때 자료손실은 발생할 것 같지 않고, intptr_t와 int가 내부표현이 다른 환경에서라도 같은 정수형 사이의 변환이 C에서 보증할 것으로 예상되기 때문에 처음 void *로 넘긴 자료가 int 범위를 넘지 않는 정수라면 문제없을 거라고 봅니다.

vacancy의 이미지


해보진 않았습니다만 ;

i가 꼭 int type이어야 하는 것이 아니라면 ;;
그냥 intptr_t 로 선언하면 되지 않나요. ;;

댓글 달기

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