Monday, October 08, 2012

Rarely Seen in the Wild

I don’t believe many of you had opportunity to observe this error before.

image

12 comments:

  1. known limitation, though personally did not meet such. But probably you can coupe it with record constants :-)

    ReplyDelete
  2. I've met that. Moved the constants out of the local scope and into global.

    ReplyDelete
  3. Anonymous12:24

    I've never seen that, I can't imagine how awfull would be the procedure involved. Maybe I'd try to simply declare a pointer then, GetMem()-Try-Finally-FreeMem() to overcome this...But I doubt this will ever append to me...

    ReplyDelete
    Replies
    1. To clarify - this happened in a machine-generated source file. My code generated a unit which declared a TDictionary and tried to load it with 2100 pairs by calling 2100 Add methods with constant parameters.

      I simply moved all constants into the global space (declared a constant 'array of string') and the problem went a way.

      Delete
    2. Anonymous21:58

      OK, thanks for the clarification...actually I was imaginating a kind of procedure with 15 local sub programs and many local variables...something like a 1500 code lines procedure...The term "awfull" was only related to my "virtual representation" of the problem ;)

      Delete
  4. Actually a lot users have seen or will see E2283 when migrating from Ansi Delphi to Unicode Delphi. The reason is that the constant limit per method is 64kB (including overhead, without duplicates) and Unicode strings need twice the size. Since each nested method has it's own 64kB I have fixed it this way in our code:

    //Old version
    procedure FooSQL(ASQL: TStrings);
    begin
    ASQL.Add('SELECT VALUE FROM FOO');
    ASQL.Add('UNION');
    ASQL.Add('SELECT VALUE FROM BAR');
    end;

    //New version
    procedure FooSQL(ASQL: TStrings);

    procedure AddFooSQL;
    begin
    ASQL.Add('SELECT VALUE FROM FOO');
    end;

    procedure AddBarSQL;
    begin
    ASQL.Add('SELECT VALUE FROM BAR');
    end;

    begin
    AddFooSQL;
    ASQL.Add('UNION');
    AddBarSQL;
    end;

    ReplyDelete
    Replies
    1. Anonymous13:29

      I think you should have a
      ASQL.Clear;
      before adding your select queries...

      Delete
    2. He didn't in the old code so he shouldn't in the new code. Assuming the old code was working as required and was desired to continue working as before. ;)

      Delete
    3. @Jolyon++, that's the #1 rule people doing refactoring should keep in mind.
      It never gets repeated enough...

      Delete
    4. Joylon, that's a big assumption. Especially if you're refactoring code because it's known to be buggy and has become impossible to maintain. My "solution" is often to transfer load to the testers - "I've refactored this, please make sure it has the same bugs".

      But that does bite me every now and then when I find something so unbelievably stupid I can't live with it. Fortunately it's often also in code that's unreachable, so I've been doing a lot of "make this private" refactoring over the last few months. Coz then the compiler says "why not remove this junk" and I can only agree.

      Delete
  5. C Johnson06:25

    Are you kidding me? There is still 16 bit limitations in the 32 bit code? That's utterly insane. The compiler has huge volumes of memory to call on. No wonder they don't want to release a 64 bit version of the toolset, it isn't fully 32 bit yet.

    argh. No, no, you're right, I'm just being over dramatic, surely everything is fine. Go ahead and marginalize me and this nonsesnse AGAIN - surely that will solve everything.

    ReplyDelete
  6. Okay we hit some compiler limitations in XE2 on the total size of an inner-procedure and inner-function, as well as total code size of a single procedure in a unit. Talk about having God-methods.

    Warren

    ReplyDelete