LinuxQuestions.org
Register a domain and help support LQ
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices



Reply
 
Search this Thread
Old 03-02-2006, 04:39 AM   #1
Thinking
Member
 
Registered: Oct 2003
Posts: 249

Rep: Reputation: 30
need solution for g++ warning on 64bit


in my prog i'm using threads
so i use pthread_create function to start them
one argument for my thread is e.g. an int value
example:
int somevar = 10;
pthread_create(&threadstruct,NULL,threadfunc,(void*)somevar);

this worked on my 32bit test environment perfectly and for the 64bit stuff it works too, but i get a warning

the first warning is: warning: cast to pointer from integer of different size
i understand why i get this, but i'm not sure, how i can solve the problem
well, on 64bit int is 4byte and void* is 8byte in size (i tested it with sizeof())
so i tried casting like this: (void*)(long*)somevar but i got the same warning
Q1: any hint wo i can remove the warning, with good valid code
i don't want to ignore such stuff

a possible solution could be something like this:
i got a similar problem on the "other" side of the thread
Code:
static void* class::threadfunc(void *arg){
  int somevar = (int)arg;
}
using the code above i got this warning: warning: cast from pointer to integer of different size
the solution was:
Code:
  int somevar = (int)(long)arg;
 
Old 03-02-2006, 05:32 AM   #2
Wim Sturkenboom
Senior Member
 
Registered: Jan 2005
Location: Roodepoort, South Africa
Distribution: Slackware 10.1/10.2/12, Ubuntu 12.04, Crunchbang Statler
Posts: 3,786

Rep: Reputation: 282Reputation: 282Reputation: 282
Code:
pthread_create(&threadstruct,NULL,threadfunc,(void*)somevar);
the last argument is incorrect. You must pass the address of somevar. The way you're doing it implies that the value in somevar contains the address.
Change it to:
Code:
pthread_create(&threadstruct,NULL,threadfunc,(void*)&somevar);
At the other side (in threadfunc) you receive a pointer. To get the int-value of the variable where the pointer points to (and not the address where it points to) use:
Code:
somevar=(int)*arg
PS: you were lucky that your 32-bit code worked.
 
Old 03-02-2006, 05:53 AM   #3
Thinking
Member
 
Registered: Oct 2003
Posts: 249

Original Poster
Rep: Reputation: 30
@Wim Sturkenboom

i'm not sure what you mean

cause: if i cast the int (value 10) to a pointer i have a pointer of value 10, so the pointer points to e.g. 0xA memory address

so its absolutly no problem to do it like i did, and it works without a problem

Q: why should it be a problem?

Quote:
The way you're doing it implies that the value in somevar contains the address.
no it doesn't
cause: the value in somevar has nothing to do with a address and the value in the pointer! which is used as an argument, HAS the value of the value of somevar
SO it CANt be a problem, CAUSE i'm not using the argument AS a pointer

hmm, correct?

if i would do this:
Code:
 prog:
    pthread_create(&threadstruct,NULL,threadfunc,somevar);
void* threadfunc(void *arg){
   int value = (int)*arg;   /// WWOOAAHH, seg fault
}
i get a seg fault

for me, (at this point right now) i think i understand why my code works without a problem and i think it will in future, cause the pointer isn't used as a pointer ;-)
it works on the 64bit arch too, but i get warnings during compile time, but it works
btw: this wasn't my idea, i got this from "unix network programming" book (<-- very good book!)
 
Old 03-02-2006, 06:31 AM   #4
dmail
Member
 
Registered: Oct 2005
Posts: 970

Rep: Reputation: Disabled
Thinking Wim Sturkenboom is correct you want to pass the address of somevar.
Quote:
The way you're doing it implies that the value in somevar contains the address.
Quote:
no it doesn't
Yes it does.


Your code example should read
if C
Code:
 prog:
    pthread_create(&threadstruct,NULL,threadfunc,&somevar);
void* threadfunc(void *arg){
   int* value = arg;
}
if C++
Code:
 prog:
    pthread_create(&threadstruct,NULL,threadfunc,(void*)&somevar);
void* threadfunc(void *arg){
   int* value = (int*)arg;
}

Last edited by dmail; 03-02-2006 at 06:35 AM.
 
Old 03-02-2006, 07:01 AM   #5
Thinking
Member
 
Registered: Oct 2003
Posts: 249

Original Poster
Rep: Reputation: 30
why?
cause this would have the problem that i use the address of a local var
so i will get a seg fault

btw:
Quote:
Thinking Wim Sturkenboom is correct you want to pass the address of somevar.
no i don't
i don't want to pass the address of somevar, i want to pass the value of somevar
 
Old 03-02-2006, 08:56 AM   #6
Wim Sturkenboom
Senior Member
 
Registered: Jan 2005
Location: Roodepoort, South Africa
Distribution: Slackware 10.1/10.2/12, Ubuntu 12.04, Crunchbang Statler
Posts: 3,786

Rep: Reputation: 282Reputation: 282Reputation: 282
Quote:
Originally Posted by Thinking
why?
cause this would have the problem that i use the address of a local var
so i will get a seg fault
No, you will not get a segfault. If you get a segfault, there is a coding mistake.

Quote:
Originally Posted by Thinking
i don't want to pass the address of somevar, i want to pass the value of somevar
You can only do so by passing the pointer (so the address) as that is what pthread_create requires.

Last edited by Wim Sturkenboom; 03-02-2006 at 08:57 AM.
 
Old 03-02-2006, 10:16 AM   #7
dmail
Member
 
Registered: Oct 2005
Posts: 970

Rep: Reputation: Disabled
Quote:
Originally Posted by Thinking
why?
cause this would have the problem that i use the address of a local var
so i will get a seg fault

btw:

no i don't
i don't want to pass the address of somevar, i want to pass the value of somevar
Ok it seems you know best.
End of help.
 
Old 03-02-2006, 10:57 AM   #8
Thinking
Member
 
Registered: Oct 2003
Posts: 249

Original Poster
Rep: Reputation: 30
@dmail
hey, i simply don't know why and there wasnt a explanation why i did something wrong
this means nobody said why it was wrong, only that it was wrong ;-)

@Wim Sturkenboom
Quote:
No, you will not get a segfault. If you get a segfault, there is a coding mistake.
yeah, damn, your right
forgot it
hmm, the problem i ran into using the address of the local variable was that the variable changed so fast, that i created 2 threads which got the SAME value of the local var, altough it should be different
example: thread1 is created and the pointer to a local var is the arg
execution of thread1 isn't done already
thread2 is created and the value of local var has changed
now thread1 and thread2 begin to execute --> i get 2 threads with the same value, but thats a failure (this scenario was my problem i had already, thats why i use the method explained a few posts before)

Quote:
You can only do so by passing the pointer (so the address) as that is what pthread_create requires.
until now i don't know what you mean
cause:
1. i look in the man page of pthread_create
2. i see, the argument for the thread "should" be a pointer (i see there stands void* arg)
3. i cast a value (from local var int simplevar) to a void* pointer, so the value of the pointer is the value of the local var
this means the pointer points to 0xA (<< just an example)
4. the thread is created and i need the value of the local variable of the function who created the thread
i simply cast back: int x = (int)arg;
this means i write the value of the pointer (the address it points to = 0xa) as a value in the local variable of the thread function
5. i have the value from simplevar in my local var x of the thread
6. i compile it - it works
7. i run it - it works
8. i debug it - it has the correct values all the time

the above points make me think, that i don't understand why my code is wrong (as you said)

another example:
Code:
#include <stdio.h>

void test(void *x);

int main(int argc,char **argv){
    int c = 10;
    test((void*)c);
    return 0;
}

void test(void *x){
    printf("%d %p\n",(int)x,x);
}
why does the above code work? it should print 10 0xa and it does

another point: why is a book (which is very very good) using the same technique? i'm sure the author knows what the does, cause the technique is used in the chapter where different server architectures are explained, this means they have to be stable

BTW: i'm not sure, but the discussion here goes into the wrong direction (from my point of view)
i just needed a hint for resolving the warnings (I GET THE WARNINGS ONLY ON 64bit!)
but maybe i'm really a complete idiot as dmail seem to think

Last edited by Thinking; 03-02-2006 at 11:05 AM.
 
Old 03-02-2006, 12:35 PM   #9
ask.jackal
LQ Newbie
 
Registered: Jan 2006
Location: India
Distribution: Suse
Posts: 12

Rep: Reputation: 0
Can u try

pthread_create(&threadstruct,NULL,threadfunc,(void*)(long)somevar);

Assume ILP architecture for ur 64 bit platforms

John Arackal
 
Old 03-02-2006, 03:59 PM   #10
Thinking
Member
 
Registered: Oct 2003
Posts: 249

Original Poster
Rep: Reputation: 30
aarrgghh
yep, it worked
orz
thx@ll
 
Old 03-03-2006, 01:06 AM   #11
Wim Sturkenboom
Senior Member
 
Registered: Jan 2005
Location: Roodepoort, South Africa
Distribution: Slackware 10.1/10.2/12, Ubuntu 12.04, Crunchbang Statler
Posts: 3,786

Rep: Reputation: 282Reputation: 282Reputation: 282
Quote:
Originally Posted by Thinking
Code:
 1 #include <stdio.h>
 2
 3 void test(void *x);
 4
 5 int main(int argc,char **argv){
 6     int c = 10;
 7     test((void*)c);
 8     return 0;
 9 }
10
11 void test(void *x){
12     printf("%d %p\n",(int)x,x);
13 }
Let's try to analyze the code. In line 6, you create a variable with the content 10. In line 7, you cast the content of the variable to a pointer-to-void and pass it to a function the requires a pointer-to-void. The only reason you have done this, is to keep the compiler happy. And yes, you're passing the value 10 to the function (as a copy of c).
This value is passed on the stack. When the function is started, it will read this value from the stack.
Now the function itself. It takes a pointer-to-void, so x is a variable that points to a void. In line 12 you print x and not the variable where x points to (so you don't use x as a pointer).
When the function is terminated, the stack is cleared (so x does not exist anymore)..
Nothing wrong with that code, it does what you told it to do but probably not what you thought it will do. I will try to show this below.

Let's modify the code slightly. After line 12, add an assignement and add an additional printf after line 7
Code:
 1 #include <stdio.h>
 2
 3 void test(void *x);
 4
 5 int main(int argc,char **argv){
 6     int c = 10;
 7     test((void*)c);
 8     printf("c = %d\n",c);
 9     return 0;
10 }
11
12 void test(void *x){
13     printf("%d %p\n",(int)x,x);
14     x=0;
15 }
You have now modified x, so x now points to somewhere else (it's still a pointer). Remember, x is on the stack.
When returning from the function, x is removed from the stack and c still contains the original value (as you passed a copy on the stack).

To get this right, below the final version.
Code:
 1 #include <stdio.h>
 2
 3 void test(void *x);
 4
 5 int main(int argc,char **argv){
 6     int c = 10;
 7     test((void*)&c);
 8     printf("c = %d\n",c);
 9     return 0;
10 }
11
12 void test(void *x){
14     printf("%d %p\n",(int)x,x);
15     *(int*)x=0;
       |  |
       |  +-- cast pointer-to-void to pointer-to-int
       +----- change variable where x points to, not x itself
16 }
We now pass (a copy of) the address of c to the function (line 7, casted to pointer-to-void), so x in the function will contain the address (and not the content). In line 15 we assign a new value to the variable where x points to (so we assign a new value to variable c). The line looks complex. To assign the value to the variable where x points to, we need to use *x; as x is a pointer-to-void, we have to cast to a pointer-to-int.

With regards to the compiler. It highly depends on the compiler which warnings you get in which situation. If you're using gcc, you now probably use a different version now and that might be more sensitive to the coding. Warnings are there to tell you that you might not get the desired result, not that you by definition do something wrong.
However, you better get rid of them. You might know today how it works, but have forgotten tomorrow. Next time you compile you might not understand why you have warnings. Andf if someone else ever has to maintain the code, he/she will go nuts (at least I would)

Hope that it helps in the understanding.

Last but not least: the modified code as I would have written it
Code:
 1 #include <stdio.h>
 2
 3 void test(void *x);
 4
 5 int main(int argc,char **argv){
 6     int c = 10;
 7     test((void*)&c);
 8     return 0;
 9 }
10
11 void test(void *x){
12     printf("%d %p\n",*(int*)x,x);
13 }
This will print the value of the variable where x points to as an int (c) as well as the address where x points to (address of c).

Last edited by Wim Sturkenboom; 03-03-2006 at 01:32 AM.
 
Old 03-03-2006, 01:10 PM   #12
Thinking
Member
 
Registered: Oct 2003
Posts: 249

Original Poster
Rep: Reputation: 30
i think i know what you mean
but that's not what i wanted to do

i just passed the socket descriptor to the thread and the main prog does just nothing with it
thats why i use it this way
only the thread needs to know about the descriptor, the main prog has, after calling pthread_create, nothing to do with the descriptor any more

i understand what you mean, but it can decrease performance if i would need to use mutex or malloc for locking/creating memory just for the descriptor

thats why i do it this way
i'm sure its not the best way, but i tested it very often and it runs ;-)

btw: thx for taking care of this
 
  


Reply

Tags
programming, threads


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
64bit Eval Issues...switched to 64bit OSS and WOW RedShirt Suse/Novell 6 01-23-2006 10:07 PM
Only for 64bit? Mikesoft Slackware 3 09-21-2005 04:11 PM
can 64bit processor run both 64bit and 32bit computers? DJOtaku Linux - General 4 09-08-2005 09:14 PM
Does 64Bit Linux have all 64Bit Packages UltimateLinux Linux - Distributions 5 02-19-2005 03:20 PM
ia 64bit ??? pleasehelpme Linux - Hardware 1 12-05-2003 07:47 AM


All times are GMT -5. The time now is 10:55 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration