Thread: More questions (relating to global doubts)

  1. #16
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Pointer arithmetic is valid only with subtract and only for pointers that point to the same block of memory (sure, you can do it for other pointers too, since the compiler doesn't actually check it - but the result is undefined, and quite often meaningless).

    So ptr1 - ptr2 is valid if ptr1 and ptr2 are pointing to the same original block of memory. And you will get the "number of elements" between the two points - not the number of bytes between. So if it's char, int, struct FILE, or some other functions, it won't make any difference. Pointer arithmetic on void * is undefined.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  2. #17
    Registered User
    Join Date
    Mar 2008
    Location
    Coimbra, Portugal
    Posts
    85
    Quote Originally Posted by matsp View Post
    Pointer arithmetic is valid only with subtract and only for pointers that point to the same block of memory (sure, you can do it for other pointers too, since the compiler doesn't actually check it - but the result is undefined, and quite often meaningless).

    So ptr1 - ptr2 is valid if ptr1 and ptr2 are pointing to the same original block of memory. And you will get the "number of elements" between the two points - not the number of bytes between. So if it's char, int, struct FILE, or some other functions, it won't make any difference. Pointer arithmetic on void * is undefined.

    --
    Mats
    Right, thanks.

    One last question to wrap everything up (for now). Are the following implementations of memcpy and memove ok? I'm not quite sure if memmove is meant to do that.

    Code:
    /* memcpy - Copy memory from source to destination with the length of num. */
    void * memcpy ( void * destination, const void * source, size_t num ) {
    char* ptr_src=(char*)source,* ptr_dest=(char*)destination;
    while(num--) *ptr_dest++ = *ptr_src++;
    return destination;
    }
    /* memmove - Copy memory from source to destination with the length of num using a secondary buffer. This is useful for overlapping memory blocks. */
    void * memmove ( void * destination, const void * source, size_t num ) {
    char* buffer = new char [num];
    memcpy((void*)buffer, source, num);
    memcpy(destination, (void*)buffer, num);
    delete[] buffer;
    return destination;
    }
    And so I thank you once more and guarantee to you that this is the last topic to be discussed, not to bother you that much.

    Jorl17

    Edit: About the functions, I haven't altered them to fix the casts and all that, so don't comment on that please, I'm already fixing it
    Last edited by Jorl17; 12-03-2008 at 06:17 AM.

  3. #18
    chococoder
    Join Date
    Nov 2004
    Posts
    515
    Quote Originally Posted by laserlight View Post
    I think that is a little too specific to be a "main mantra"

    Maybe "strive for loose coupling and high cohesion" would be more like it.
    Globals are evil, period.
    Company I used to work for had a plaque on the wall (they were a Progress shop, where globals were quite normal) reading "the only good global is an eliminated global".

  4. #19
    The larch
    Join Date
    May 2006
    Posts
    3,573
    I'm sorry but who else in this thread are discussing using globals? I take "global doubt" in the title to mean "general questions"...

    Besides, as OP is reimplementing the standard C/C++ library, it does use globals (rand/srand, std::cout and friends) and static buffers/variables, so what can you do?
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  5. #20
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Code:
    void * memmove ( void * destination, const void * source, size_t num ) {
    char* buffer = new char [num];
    memcpy((void*)buffer, source, num);
    memcpy(destination, (void*)buffer, num);
    delete[] buffer;
    return destination;
    }
    1. Standard C functions should not use C++ functionality.
    2. What if the user tries to copy 1GB of memory - you will most likely fail the new.

    The normal memmove deterimens if the copy is overlapping, and if so, copies in a direction that avoids overwriting the data, otherwise just call memcpy() in the first place.

    Also, your memcpy() is FAR from the optimal performance.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  6. #21
    The larch
    Join Date
    May 2006
    Posts
    3,573
    How does memmove determine overlaps?
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  7. #22
    Registered User
    Join Date
    Mar 2008
    Location
    Coimbra, Portugal
    Posts
    85
    Quote Originally Posted by matsp View Post
    Code:
    void * memmove ( void * destination, const void * source, size_t num ) {
    char* buffer = new char [num];
    memcpy((void*)buffer, source, num);
    memcpy(destination, (void*)buffer, num);
    delete[] buffer;
    return destination;
    }
    1. Standard C functions should not use C++ functionality.
    2. What if the user tries to copy 1GB of memory - you will most likely fail the new.

    The normal memmove deterimens if the copy is overlapping, and if so, copies in a direction that avoids overwriting the data, otherwise just call memcpy() in the first place.

    Also, your memcpy() is FAR from the optimal performance.

    --
    Mats
    Right, so replace c++ syntax with C syntax, shouldn't be too harsh. How can I copy memory without allocating new one? And how would I determine if they overlap? Would it be done using pointer arithmetic? Why is memcpy such a performance hit atm?

  8. #23
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by anon View Post
    How does memmove determine overlaps?
    Comparing the range of source, source+len with destination, destination+length. If destination or destination+ len is within source to source + length, then it is an overlap.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  9. #24
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Jorl17 View Post
    Right, so replace c++ syntax with C syntax, shouldn't be too harsh. How can I copy memory without allocating new one?
    By copying in the opposite direction of there is an overlap. (so start at source+length-1 and copy to destination+length-1 - the same way you would do if you have an array that you want insert something into - you start at the back and copy each down one up to the point where you want the empty location).

    And how would I determine if they overlap? Would it be done using pointer arithmetic?
    Check out my reply to anon.

    Why is memcpy such a performance hit atm?
    Because it is copying a byte at a time, which is quite slow on all machines. It is correct (and correctness is better than performance).

    Some of the work I did with Mike Wall at AMD is published here. It's not EXACTLY memcopy, but it explains some of the basic principles
    http://www.amd.com.cn/CHCN/Processor...9_7451,00.html
    (Scroll to the bottom for a 2002 presentation about "Block Prefetching").

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  10. #25
    Registered User
    Join Date
    Mar 2008
    Location
    Coimbra, Portugal
    Posts
    85
    Ok, thanks. Not quite sure I got it, but I'll read some articles and take a look at some implementations.

    Thanks for the link and thanks for everybody's help.

    If I have any questions I'll just start a new topic and be even MORE evil :P

    Jorl

  11. #26
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    Some of the work I did with Mike Wall at AMD is published here.
    O_o

    True to my nature, I read that for funsies. I found a bug, let's call it a bug, in my code preventing the performance I had expected because of that. So, yea, thanks for that. ^_^

    Soma

  12. #27
    Registered User
    Join Date
    Mar 2008
    Location
    Coimbra, Portugal
    Posts
    85
    Just to tell you I finally understood all the fuzz about overlapping memory blocks.

    following: http://www.student.cs.uwaterloo.ca/~...8c-source.html

    The inline code explanation there is absolutely amazing for me. I'd been playing with remote controls trying to represent memory blocks here but didn't seem to understand a thing!

    Jorl

  13. #28
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    And as you can see, the linked memmov use "long" size if possible - it's only doing the simplest form of aligned copies, but that will be very close to "sizeof(long)" times faster than a char copy.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  14. #29
    Registered User
    Join Date
    Mar 2008
    Location
    Coimbra, Portugal
    Posts
    85
    Indeed I noticed that as soon as I saw it

  15. #30
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Here's my attempt:

    Code:
    const char* 
    strrchr( const char* str, int val )
    {
        const char* 
            ptr;
        for( ptr = 0; *str; ++str )
        {
            if( *str == val )
                ptr = str;
        }
        return ptr;
    }
    
    char* 
    strncpy( char* dst, const char* src, size_t len )
    {
        char* 
            cpy = dst;
        while( len-- )
        {
            *cpy++ = *src++;
        }
        *cpy = 0;
        return dst;
    }
    
    
    size_t
    strspn( const char* str, const char* pat )
    {
        const char*
            bas = str;
        int
            fnd = 1;
        for( ; *str && fnd; ++str )
        {
            fnd = 0;
            for( const char* ptr = pat; *ptr; ++ptr )
            {
                if( *str == *ptr )
                {
                    fnd = 1;
                    break;
                }                
            }
        }
        return str - bas;
    }
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. basic question about global variables
    By radeberger in forum C++ Programming
    Replies: 0
    Last Post: 04-06-2009, 12:54 AM
  2. Best way to avoid using global variables
    By Canadian0469 in forum C++ Programming
    Replies: 7
    Last Post: 12-18-2008, 12:02 PM
  3. A very long list of questions... maybe to long...
    By Ravens'sWrath in forum C Programming
    Replies: 16
    Last Post: 05-16-2007, 05:36 AM
  4. Global objects and exceptions
    By drrngrvy in forum C++ Programming
    Replies: 1
    Last Post: 09-29-2006, 07:37 AM
  5. Replies: 26
    Last Post: 03-20-2004, 02:59 PM