Incomprehensible syntax

procedure MikuInit( const Sprite : zglPSprite2D ); begin Sprite.X := 800 + random( 800 ); Sprite.Y := random( 600 - 128 ); zgl_GetMem( Sprite.Data, SizeOf( zglTPoint2D ) ); with zglTPoint2D( Sprite.Data^ ) do begin X := -random( 10 ) / 5 - 0.5; Y := ( random( 10 ) - 5 ) / 5; end; end; 

Explain why a constant parameter declared in a procedure as constant changes inside it. Written in FreePascal. Why by the way there is no label FreePascal?

    3 answers 3

    The mark of const in this case indicates that the structure is not copied to the function when passed to the function, but passed by reference, however, unlike var , the link is protected, so you cannot write such code:

     Sprite:= NewSprite; 

    However, this "protection" concerns the Sprite itself, but does not concern its fields. That is, in this case, you cannot change one structure for another, but nobody forbids changing the structure itself.

    Since there were disagreements, I will clarify my, perhaps, not quite correct answer. This is typical if PRECord is passed as a parameter, that is, a variable of the type pointer to record . Usually they are marked with the prefix P, in contrast to the records themselves, which are marked with the prefix T.

    In our example, zgl P Sprite2D , which is most likely a pointer (otherwise it would be zgl T Sprite2D ).

    In the case of zgl T Sprite2D code really does not compile.

    • Follow the first link in my answer. - karmadro4
    • take the module from here: zengl.googlecode.com/svn-history/r928/trunk/src/… and this function will compile. You might think that the data types are set in pascal only as you have in the example ... - AlexAndR
    • Unfortunately, the answer @ karmadro4 does not add a comment, I will add here. The second link read, about reducing the size of the stack there is also written. About the logical Hungarian ... Well, what else could be meant by zglPSprite2D? Why then is there P, if not to emphasize that this is a pointer? PRecord is automatically dereferenced and behaves like a TRecord, so ... But I will not argue, I must look at the assembler, but this is not worth it. - AlexAndR
    • I think that once the OP is satisfied with the answer, that's fine. Here , all the familiar faces discuss automatic dereference. - karmadro4

    Transformed from comment to give the ability to remove the wrong answer.

    This example is non-working.

    From the logic of this procedure, it clearly follows that the parameter by reference must be declared as var . Why the author of the example slovenously declared him to be a const remains a mystery to me.

    • the code doesn't compile like this: type zglPSprite2D = record X, Y: Integer; Data: Pointer; end; type zglTPoint2D = record X, Y: Real; end; but it compiles like this: type zglPSprite2D = ^ zglTSprite2D; zglPSEngine2D = ^ zglTSEngine2D; zglTSEngine2D = record Count: LongWord; List: array of zglPSprite2D; end; zglTSprite2D = record X, Y: Single; Data: Pointer; end; type zglTPoint2D = record X, Y: Real; end; - AlexAndR
    • It is compiled because you declared a pointer and bicycles with it, passing a parameter by reference, and then use automatic dereferencing of pointers to structured types. What is the meaning of const in this ad? - karmadro4
    • It was not I who announced and I didn’t bicycling, this is a specific piece of code from the network, in the comments on my answer link to it. In real life, this technique is used constantly, for example, for function calls from Dll. Why did they write like that - the question is not for me, I answered what was asked. Alternatively, const could be used so that they could not return the garbage to the place of the call instead of the record. - AlexAndR
    • > save 4 bytes in the stack. Passing an actual parameter by reference is equivalent to passing by the value of a pointer to this parameter. In the case of passing the pointer parameter by reference ( constant pointer to pointer ), I do not see any savings. > In real life, such a technique is used constantly, for example, for function calls from Dll. There is no point in shielding dolls from pointers and not using them. - karmadro4
    • without the const keyword, the pointer address is copied to the stack; this is just 4 bytes. Using const allows you to optimize the code for the structured and string-type parameters. (from the Delphi help) I'm not in doubtful optimizations, but using the word const, other things being equal, is preferable for strings and structures. To finish the topic I remind you that the question was: "why the value changes", and not why someone wrote the curve, in your opinion, the code. - AlexAndR

    Because structures are not constants.

    There is a maximum recorded address of the pointer.

    That is, directly zglPSprite2D:= zglPSprite2DNEW; maybe it will not, and change attributes - always welcome.

    And it at all at you? ))

    • I can not imagine, then why the author in this case used it. The program is quite short, this is an example of using one feature in a 2D engine. - Paul
    • Mlyn yes. I screwed up)) We'll write off the fact that I did not see the pascal from the first year or this is a freak of a local animal) - SilverIce
    • @SilverIce, but why then guess? :( I am in doubt whether to put a minus or not, the last edit is completely non-valuable. - karmadro4