How do you usually declare pointer parameters for methods?

How do you usually declare pointer parameters for methods?

function InOut(const aIn: TStrings; const aOut: TStrings);

should be most efficient but it "feels" wrong to put const in front of a pointer to an object that my function will change (the object, not the pointer).

Any conventions, insights?

Comments

  1. Why do you think that placing a const before an instance parameter makes it more efficient?

    ReplyDelete
  2. I always write const, var or out for both, value and reference types and never a parameter without one of these modifiers.

    ReplyDelete
  3. const = your container is constant, not the contents of your container.

    ReplyDelete
  4. Martin Wienold Then you give away the possibility to change the parameter only for internal use. One would need a separate local variable for that which is initialized with the const parameter. Seems a bit redundant to me. I often use this when the parameter has to be manipulated for internal processing f.i. a 1-based index is decremented to a 0-based one or a string is prepared or cleaned before processing. This sort of parameters (i.e. non-var or by-value) have had its use case since the invention of Pascal.

    ReplyDelete
  5. Uwe Raabe it might not. I do not know. I read that when you declare const the compiler can optimise. I do not know enough about the calling conventions to decide.

    ReplyDelete
  6. Lars Fosdal, yes. "an object that my function...".

    ReplyDelete
  7. Dany Marmur​ in this case not more efficient. Unless you have timed it. Don't optimise prematurely. Don't let your erroneous understanding of performance dictate your coding style. The tail wags the dog.

    ReplyDelete
  8. Martin Wienold, ok. You are close to what i am on about. I simply want to be a bit more consequent. Care to elaborate? TIA.

    ReplyDelete
  9. David Heffernan - exactly why i posted from start! See i am not 100% sure of what happens. I think i understand that when you have a "larger" object on the stack "const" can optimize to avoid unnecessary copying at object initialisation. But a pointer is just that. Yes?

    Regarding my understanding you could say that all non-complete understandings are erroneous. Not asking or doing research in that context is borders on criminal.

    However, my understanding of premature optimisation in particular is sound and comes from 25 years of experience - "The whole point of getting things done is knowing what to leave undone." -Oswald Chambers. Proof of concept being i actually deliver working stuff to my clients - something that much of my competition fails to do.

    ReplyDelete
  10. What are talking about. You already decided to use const for reasons that are erroneous. It doesn't help performance for pointer sized, or smaller, arguments. It doesn't change anything at the ABI level.

    And I'm really not sure what you mean by copying at object initialisation. Those terms don't tally with anything I recognise. You aren't initialising anything, you are passing arguments.

    ReplyDelete
  11. David Heffernan, i cannot find the place where i have announced a decision. Sorry.

    Yes - as i already stated - partial confusion regarding the optimisation bit. But mainly i am interested in coding style and mostly for my own (revisiting after years) sake.

    I can also agree that my nomenclature sucks. I never had the privilege to study these things and since english isn't even my second language i do have to put more time and effort into writing here.

    Another mistake i did posting this time was not to google first. Had i found this i would could have written up my actual question in a much clearer way. It does not answer my question but it sure straighten some things out. Will try to stop myself next time.

    Thank you all for your efforts! (Still interested in Martin Wienold's ideas though).

    stackoverflow.com - Are there any advantages in using const parameters with an ordinal type?

    ReplyDelete
  12. Main reason to const things (yes in cross platform code I even const all object parameters because under ARC that matters bigtime!) is the compatibility with anonymous methods where I use some.

    SysUtils.TFunc unfortunately is not compatible with for example SysUtils.StrToInt because the parameter of StrToInt is const.

    However in many of my APIs that consume anonymous methods I tend to use anonymous method types that have const parameters because if some of the type parameters being used (mostly referring to generic types) is one that benefits of being passed as const I get this benefit rather than wasting performance to unnecessary ref counting (strings, managed records, interfaces, objects on ARC).

    So I have my own Func which is reference to function(const arg: T): TResult which then is compatible with StrToInt... however not with IntToStr anymore because there the parameter is not const - hence I rather const my parameters on routines that are candidates of being passed as anonymous methods.

    Yes, I have seen code that used generics/anonymous methods that became terribly slow not because generics or anonymous methods but because parameters being passed through them caused refcounting/copyrecord all over the place.

    The case that Uwe Raabe mentioned is rather rare and it really does not hurt at all to use a local variable. I remember one case where I had code that caused me to "unconst" a parameter because the code became so much easier (I think it was simply because the value was passed to another routine as var or out parameter which did not work with a const parameter)

    ReplyDelete
  13. Consider this:

    function InOut(const aIn: TStrings; out aOut: TStrings);

    Const parameters: "Using const allows the compiler to optimize code for structured - and string-type parameters. It also provides a safeguard against unintentionally passing a parameter by reference to another routine."

    Out parameters: "An out parameter, like a variable parameter, is passed by reference. With an out parameter, however, the initial value of the referenced variable is discarded by the routine it is passed to. The out parameter is for output only; that is, it tells the function or procedure where to store output, but does not provide any input."

    ReplyDelete
  14. David Heffernan "It doesn't help performance for pointer sized, or smaller, arguments. It doesn't change anything at the ABI level."

    Isn't that statement some what erroneous, as Strings and Interfaces are passed by pointer and without the const, the compiler will add in a hidden try-finally section, which is a real performance hit under Win32?

    ReplyDelete
  15. You are right, I neglected managed types. I was concentrating on the types in the original question I guess. And ignoring ARC.

    What irritates me is that we even have const. Suppose it didn't exist. We could still have the optimisation. The compiler could analyse the implementation, see that no modifications are made, and skint he reference counting code.

    ReplyDelete
  16. Const parameters are useful as an additional self-test level even for simple types (Integer, Char, enumerated etc.).

    ReplyDelete

Post a Comment