& operator

This is a discussion on & operator within the C Programming forums, part of the General Programming Boards category; Hello, I have the following program and I observe that the f function prints different values on its two calls. ...

  1. #1
    Registered User
    Join Date
    Apr 2010
    Posts
    4

    & operator

    Hello,

    I have the following program and I observe that the f function prints different values on its two calls. The correct result is the second one.
    Can anyone explain me please, exactly what the & operator does?

    Thank you

    Code:
    #include <stdio.h>
    int m[5][5];
    
    void f(int** v){
    	printf("*v=%p v=%p\n",*v,v);
    }
    
    int main(){
    	printf("m[4]=%p\n",m[4]);
    	f(&m[4]);
    	int*ptr = m[4];
    	f(&ptr);
    	return 0;
    }
    Last edited by stef8803; 04-29-2010 at 01:08 PM.

  2. #2
    Registered User
    Join Date
    Jan 2009
    Location
    Australia
    Posts
    375
    & is the address-of operator. Is supplies the address of the variable that it prefixes.

    All variables are held in memory somewhere, so the & operator returns that address.

  3. #3
    Registered User
    Join Date
    Oct 2008
    Posts
    1,262
    Quote Originally Posted by DeadPlanet View Post
    All variables are held in memory somewhere, so the & operator returns that address.
    Pedantically, not all variables are held in memory. That is, not in the addressable RAM. Some variables might only be stored in registers. But if required (eg. because you do use the operator and it can't be optimized away), it IS stored in memory.

    It might be too difficult to delve into that subject now for you, but as some forum goers will know, I'm not a fan of wrong information to keep things simple (It wasn't even terribly wrong, but ok).

  4. #4
    Registered User
    Join Date
    Apr 2010
    Posts
    4
    Quote Originally Posted by DeadPlanet View Post
    & is the address-of operator. Is supplies the address of the variable that it prefixes.

    All variables are held in memory somewhere, so the & operator returns that address.
    Please run the program first. I know what the & operator should do, but it fails in this case and I wonder why.
    I suppose this happens because m[4] is a kind of a constant, and doesn't have an address. So &m[4] returns m[4] instead of it's address.
    However it doesn't sound like a complete explanation.

    PS It could be useful to mention that I compiled this program using gcc.
    Last edited by stef8803; 04-29-2010 at 08:44 AM.

  5. #5
    Banned
    Join Date
    May 2007
    Location
    Berkeley, CA
    Posts
    329
    Quote Originally Posted by DeadPlanet View Post
    & is the address-of operator. Is supplies the address of the variable that it prefixes.

    All variables are held in memory somewhere, so the & operator returns that address.

    Wait, what's that?! Oh look, the SUN machines here at work here return the offset, and not the address when I use the & operator!

  6. #6
    Registered User
    Join Date
    Jan 2009
    Location
    Australia
    Posts
    375
    Wait, what's that?! Oh look, the SUN machines here at work here return the offset, and not the address when I use the & operator!
    Ok, my apologies. I'm man enough to admit when I am wrong. Nothing like a little humility though.

    EDIT: For clarification, I know that EVOEx also proved me wrong, the 'tone' of that post just didn't seem to require a reply.
    Last edited by DeadPlanet; 04-29-2010 at 09:18 AM.

  7. #7
    Registered User whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    7,638
    Quote Originally Posted by stef8803 View Post
    Please run the program first. I know what the & operator should do, but it fails in this case and I wonder why.
    I suppose this happens because m[4] is a kind of a constant, and doesn't have an address. So &m[4] returns m[4] instead of it's address.
    However it doesn't sound like a complete explanation.

    PS It could be useful to mention that I compiled this program using gcc.
    Without reposting what you wrote, you did this

    Code:
    void*ptr = m[4];
    In C, m is declared as an array of arrays so the type of m[4] is actually int[5]. If the above statement did not trigger a complaint from the compiler it is because the expression m[4] idecayed to a pointer type from its array type. I'm actually not sure if this is proper C, but in any event, your function call f(&ptr); worked because you created a temporary pointer. You could do probably also do this.

    Code:
    f( (void**)&m[4] );
    Or, you might also be able to change the pointer type to int (*v)[5] in function f.
    Code:
    int main (void)
    {
       int m[5][5] = { {0, } };
       int (*v)[5] = &m[4];
       printf ("address of v is %p\n" , (void*)v);
       /*..*/
       return 0;
    }
    Also %p is the format specifier for pointer addresses. Technically speaking, %x is for hex values even if it's the same difference.
    Last edited by whiteflags; 04-29-2010 at 09:56 AM.

  8. #8
    Registered User
    Join Date
    Apr 2010
    Posts
    4
    Ok, here's how the program works:

    m[4]=004040C0
    *v=00000000 v=004040C0
    *v=004040C0 v=0023FF74

    I can't understand why &m[4] doesn't get the address of m[4].
    As you can observe, when calling f(&m[4]), v is equal to m[4] and not *v, as it should be in my opinion.

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,452
    Quote Originally Posted by DeadPlanet
    Ok, my apologies. I'm man enough to admit when I am wrong. Nothing like a little humility though.
    You're not wrong about unary & being the address-of operator though. The offset that Overworked_PhD mentions is an address with respect to C.

    Quote Originally Posted by stef8803
    I can't understand why &m[4] doesn't get the address of m[4].
    As you can observe, when calling f(&m[4]), v is equal to m[4] and not *v, as it should be in my opinion.
    If you are talking about the original snippet that you posted, then you should take note of what whiteflags stated: the type of &m[4] is not int**, but int (*)[5].
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    Banned
    Join Date
    May 2007
    Location
    Berkeley, CA
    Posts
    329
    Quote Originally Posted by laserlight View Post
    You're not wrong about unary & being the address-of operator though. The offset that Overworked_PhD mentions is an address with respect to C.


    If you are talking about the original snippet that you posted, then you should take note of what whiteflags stated: the type of &m[4] is not int**, but int (*)[5].
    There are some platforms at work where the offset really isn't the address. And yes, these are conforming C compilers since the ANSI/ISO standard speaks of pointers in terms of objects and not addresses.

  11. #11
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,452
    Quote Originally Posted by Overworked_PhD
    There are some platforms at work where the offset really isn't the address. And yes, these are conforming C compilers since the ANSI/ISO standard speaks of pointers in terms of objects and not addresses.
    What the standard speaks is:
    Quote Originally Posted by C99 Section 6.5.3.2 Paragraph 3
    The unary & operator returns the address of its operand.
    But as I said, this is just from the perspective of C, so you are otherwise correct.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  12. #12
    Registered User
    Join Date
    Apr 2010
    Posts
    4
    Quote Originally Posted by laserlight View Post
    You're not wrong about unary & being the address-of operator though. The offset that Overworked_PhD mentions is an address with respect to C.


    If you are talking about the original snippet that you posted, then you should take note of what whiteflags stated: the type of &m[4] is not int**, but int (*)[5].
    I was using int[5] as an int*, I thought they were roughly the same.
    Now I understand.
    Thank you very much.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. why can't my perceptron learn correctly?
    By yann in forum C Programming
    Replies: 25
    Last Post: 10-15-2010, 12:26 AM
  2. Smart pointer class
    By Elysia in forum C++ Programming
    Replies: 63
    Last Post: 11-03-2007, 07:05 AM
  3. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  4. Operator Overloading (Bug, or error in code?)
    By QuietWhistler in forum C++ Programming
    Replies: 2
    Last Post: 01-25-2006, 07:38 AM
  5. operator overloading and dynamic memory program
    By jlmac2001 in forum C++ Programming
    Replies: 3
    Last Post: 04-06-2003, 11:51 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21