Jump to content

balabuev

Members
  • Content Count

    241
  • Joined

  • Last visited

  • Days Won

    2

Posts posted by balabuev


  1. On 4/8/2024 at 11:51 PM, Remy Lebeau said:

    also, you don't need to use "Self.").  You can also use an inline variable to simplify your example further

    Self is used for demo code clarity, of course it is not needed here. Yes, you right the code is shorter with inline variables (i don't have them in mind because I usually write libraries for XE2+, so my fail here).

     

    On 4/8/2024 at 11:51 PM, Remy Lebeau said:

    As for the invalid cast errors, they are probably the compiler trying to CALL the method first

    Yes, the side effect of bracesless functions calls. Still it looks like inconsistency. By the way, as I mentioned, even "@ProcX" does not help.

     

    On 4/8/2024 at 11:51 PM, Remy Lebeau said:

    Do note that in the original TStream code, using @TStream.Seek like above won't work since Seek() is overloaded

    Yes, you right. And the ClassTAncestor hack is needed because Seek is a virtual method, otherwise we can resolve overloads simpler:

    Base := TStream(nil).Seek;

     


  2. I see the topic is old already, but anyway, I'm searching for something faster. So, here is my try:

    type
      TAncestor = class
        procedure ProcX; virtual;
        procedure DoSomething;
      end;
    
      TDescendantA = class(TAncestor) 
        procedure ProcX; override;
      end;
    
      TDescendantB = class(TAncestor) 
      end;
    
    procedure TAncestor.DoSomething;
    type
      TProcX = procedure of object;
    var
      md: TProcX;
    begin
      md := Self.ProcX;
      if TMethod(md).Code <> @TAncestor.ProcX then
        // Overridden.
      else
        // Not overridden.
    end;

     

    This is faster than previous solutions, but I don't like complicated long code (type declaration, md variable). Btw:

     

    procedure TAncestor.DoSomething;
    type
      TProcX = procedure of object;
    var
      md: TProcX;
    begin
      md := Self.ProcX; // Compiles.  
      md := TProcX(Self.ProcX); // Invalid cast :)).
      
      // And so:
      
      if TMethod(Self.ProcX).Code = ... then // Also invalid cast.
      	;
      
      if TMethod(TProcX(Self.ProcX)).Code = ... then // Also invalid cast.
      	;
        
      // Using "@Self.ProcX" does not work too...
    end;

     


  3. 3 minutes ago, Dalija Prasnikar said:

    In that context how complicated feature might be matters.

    Well, if Embarcadero afraid every single conditional jump, I have nothing more to say. However, even this additional stuff, which has been noted several times, have not been explained. Seems to me invented on-the-fly...


  4. If we speak about priority, then I agree, goto is not a frequently used feature. And goto with try/finally - even more rare :). 

     

    9 minutes ago, Kas Ob. said:

    It is big, the compiler is so outdated

    They created code generation for other platforms, like x64 and Android. They added anonimous methods and inline variables - features much more complex than the discussing "goto". So, I understand the answers, like "its not a high priority thing". But, I cannot understand the answers like "its impossible/hard to implement" or "ooo, it will require one additional conditional jump" :) Who cares really about one additional jump?..

     

    I'm personally would prefer that they fix "undo" functionality in the code editor. Code editor, like compilers, is the heart of the IDE...


  5. 2 minutes ago, David Heffernan said:

    Why are you arguing. Surely you have an actual problem to solve. Why don't you just do that. You know all you need to know now. 

    Actually, I occasionnaly found my old post with possible combinations of try/finally and try/except and gotos. Re-read it, and found that all cases are ok, except of one. After that I simply followed comments in the topic 🙂. It's strange to me that people here do not want to make the language more self-consistent, especially in this particular case, where not big amount of work in the compiler is required.


  6. 23 minutes ago, Stefan Glienke said:

    It's cute that you only have x86 in mind when discussing this.

    You right, but I think other platforms work similarly. Can check in Win64 and Android. But, what is more important is that it's absolutely identical to Break or Continue, and because of that it will not require, as you said, "significant work in the compiler".

    23 minutes ago, Stefan Glienke said:

    See how the C# spec defines the behavior of a goto out of a try block

    Yes, I wanted to mention that also.


  7. 2 minutes ago, Dalija Prasnikar said:

    The jump to finally happens behind that call.

    Things, which happens inside finally handling block is not relevant to the discussion, because it happening independent of what exactly causes finally code to execute. It may be Break, it may be exception raising.

     

    6 minutes ago, Dalija Prasnikar said:

    Like I have already said, I was wrong that there is only single jump involved for the Break and Continue. 

    If we speak about "involved" - yes, several jumps are involved. But, this is a nature of try/finally. They are equally emitted for any finally block, and involved even when finally is executed because of exception raising - the main reason for "finally" to exist. So, these jumps are not even related specifically to Break or Continue.

     

    However, we mostly discussing here enchancing of the compiler - the newly required functionality is matter, not existing currently. So, I claim that to support goto with finally(ies) the emitted code will not be in any way more complex than it is now for Break. Specifically, a single "call" instruction for every exiting finally, and a single unconditionnal jump instruction.

     

    To be honest, managed local variables in a destination scope complicates the thing, but this is a separate, independed of try/finally aspect.

     

     


  8. 1 minute ago, Stefan Glienke said:

    It would require properly transferring control to the finally blocks and then transferring control to the target label

    It would require transferring control to the finally blocks just identically to Break and Continue - One "call" instruction for each exiting finally and one unconditional jump.


  9. 7 minutes ago, Dalija Prasnikar said:

    You are right, I forgot that there could be code in the loop after the finally, which requires additional jump. 

    You are wrong. Can you provide sample code, in which a single Break will require more than one jump? I mean the code in which I can comment the Break and compare generated asm.


  10. 3 hours ago, Dalija Prasnikar said:

    while goto would require two jumps, one of them conditional

    I cannot imagine, where the difference come from. Moreover, handling finally is a "call", not jump. So, what Break do, is a single "call" to handle each exiting try/finally, and then - usual jump.

     

    image.thumb.png.304ef3c2cddb902812f34cb6ca0b9151.png

     

    So, goto should do the same.

     

     


  11. 9 hours ago, David Heffernan said:

    Well, you say that, but it's the placement of the label that determines whether this an error or not so I think that's fine

    No doubt that eror placement is not good too, since the message itself is about specific goto statement, not about the label generally. But, it's not matter. What is matter - the error itself. They implemented actually the same under-the-hood functionality for Break/Continue, but ignored goto. Because, who need it, right?


  12. 13 minutes ago, David Heffernan said:

    For the sake of future readers, this example is not minimal.

    Yes, my fail. Should be:

    try
      goto L1; // Compile error, but why?
    finally
    end;
    
    L1:

     

    1 hour ago, Kas Ob. said:

    GoTo, will make a mess and hide some dangerous behavior and i doubt Delphi compiler will be able to handle it

    Not more mess than Break, Continue or usual "goto".


  13. Do I understand correctly that a control, which is not a TWinControl (for example, TLabel), has no way to implement flicker free drawing with VCL Styles turned on?

     

    It seems that the parent form erases its own background via TFormStyleHook.PaintBackground not excluding child controls. This happens in both: Form.DoubleBuffered = False and Form.DoubleBuffered = True modes.


  14. 7 minutes ago, Davide Angeli said:

    When I come back to 10.4 I have to close and reopen the IDE at least once every 15 minutes and the LSP is totally unusable...

    I cannot agree with that. Moreover, 10.4 has a way to disable LSP in favor of old code insight engine.


  15. 11 minutes ago, Brandon Staggs said:

    What I find frustrating about this is that when CTRL+Click doesn't work, often CTRL+G on the same symbol DOES work

    Ctrl+G is also quite limited. Not work for stuff from library files, not work for unit names in "uses" clause.


  16. So, I have to say that killing LSP helps, but not always. What me bothers a lot - is that LSP behavior depends of UI actions - open/close a library unit, switch between opened files in the code editor. It seems to me insane. After killing LSP the first Ctrl+Click on a library type identifier never works. Clicking again on the same identifier - may work fine.

     

    Also, I've never seen that Ctrl+Click on an "inherited" keyword worked, despite the fact that this was promoted as a new IDE feature.

     

     

×