Thread: const

  1. #1
    Registered User
    Join Date
    Aug 2001


    is it safe having a function like:
    void func(void *out_p, const void *in_p);
    and pass a pointer to the same object as both arguments?
    since the object passed as the arguments is both - const and non-const.
    so might optimization produce wrong code in that case - or are arguments skipped by optimization anyway?

    .) read from *in_p
    .) modify *out_p - thus the object pointed to by in_p has changed.
    read from *in_p again. since the object pointed to by in_p was declared const, the compiler might think it has not changed and do some optimization. so instead of reading the changed version, the original version would be read.
    signature under construction

  2. #2
    Registered User
    Join Date
    Nov 2001

    completely valid be careful parameters


  3. #3
    Registered User
    Join Date
    Jan 2005
    Compiler optimization should never change the expected behavior of a program. If whatever the object is can handle being written to and read from at the same time, then the fact that you pass two pointers to the same object shouldn't have any negative effect.

  4. #4
    Registered User
    Join Date
    Apr 2006
    You might have a problem passing the same object by pointer like that, but it would not be because of optimisation. More likely you might run into a problem if func() accesses in_p throughout it's execution, expecting the value(s) pointed to to stay the same.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  5. #5
    Registered User
    Join Date
    Aug 2001
    well i couldn't make up a good example, where passing the same object as const and non-const would make sense, WITHOUT creating a temporary copy
    in the function.
    (probably, because there is none)

    void func(IntVector &r_out, const IntVector &r_in)
      register tmp = r_in[1]; // store r_in[1] into a register
      r_out[1] = r_in[0]; // assume that (&r_out == &r_in) holds in this example, so r_in[1] is changed indirectly
      std::cout << r_in[1] << std::endl; // ?! what is being printed here, the original r_in[0] (which would be expected) or the original r_in[1]
    so an optimizing compiler might assume, that r_in[1] could be replaced by the register variable tmp - thus not re-read it again.
    this is not the expected behaviour when looking at the code.

    on the other hand, writing to an output object, which modifies the input object at the same time, and then reading modified data from the input object again is a logic mistake anyway.
    (because when having a function that accepts input and output as seperate arguments, then its clearly intended for having different objects passed to it. if such function should be able to handle the case, that input and output refer to the same object, then a temporary copy of the input has to be created.)
    signature under construction

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    The edge of the known universe
    > Compiler optimization should never change the expected behavior of a program
    This is only true of a correct program.
    Optimisation frequently breaks poorly written code for one reason or another.

    Most standard C library functions (memmove is a noted and specific exception) react pretty badly to overlapping memory blocks.

    > this is not the expected behaviour when looking at the code
    No, but you might expect it when you turn on the optimiser, and expect references through const to be read only once. If you then go and change it via another route, then you're in for a surprise.

    This is exactly the reason (namely aliasing) which prevents some kinds of optimisation from taking place.
    It's also the reason why C99 added the "restrict" keyword to allow checks to be performed to ensure that multiple references to the same object (possibly with different attributes) do not exist.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Registered User
    Join Date
    Jan 2005
    >> Optimisation frequently breaks poorly written code for one reason or another.
    You are right, assuming by "poorly written" you mean incorrect. I might call the original code poorly written even if it was legally valid, but the optimization shouldn't break it if that was the case.

  8. #8
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Some compilers (such as G++) have proprietary extensions that allow the programmer to mark arguments as non-aliased, i.e. the optimizer may assume that all pointers point to different objects. Passing the same object to such a function may cause problems.
    All the buzzt!

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Polynomials and ADT's
    By Emeighty in forum C++ Programming
    Replies: 20
    Last Post: 08-19-2008, 08:32 AM
  2. Undefined Reference Compiling Error
    By AlakaAlaki in forum C++ Programming
    Replies: 1
    Last Post: 06-27-2008, 11:45 AM
  3. Drawing Program
    By Max_Payne in forum C++ Programming
    Replies: 21
    Last Post: 12-21-2007, 05:34 PM
  4. Certain functions
    By Lurker in forum C++ Programming
    Replies: 3
    Last Post: 12-26-2003, 01:26 AM
  5. Half-life SDK, where are the constants?
    By bennyandthejets in forum Game Programming
    Replies: 29
    Last Post: 08-25-2003, 11:58 AM