-1

Various sources appear to discourage typed constants in favour of more object-oriented techniques. For example DelphiBasics where they are described as "very odd" and StackOverflow Question which gives some background on why they might be used. Here is an example of a true and a typed constant.

const
  RESULTS_BASIC1        = $01;  // True constant
  RESULTS_BASIC2: BYTE  = $01;  // Typed constant

I'm using Delphi 7 and FastMM4, and a leak of a single TCriticalSection is being reported. After enabling a detailed map file in the Project Options, the FastMM4 stack trace shows something like this:

402E58 [StConst][StConst][@GetMem]
40454B [WinConvert][WinConvert][d_len]
404926 [Main][Main][EXAMPLE_TYPED_CONSTANT1]
...

If I then remove the typed constant, the same TCriticalSection is reported as being leaked...on the next typed constant! After slowing removing one typed constant after another, I'm still no nearer to the "true" source of the leak.

Two related questions:

1) Could a typed constant (which are actually variables with a memory address) be the true source of the memory leak? Could FastMM4 be reporting the leak in error?

2) Should typed constants really be avoided and if so, what is the recommended alternative? For example, say I'm using an elapsed processor TickCount (an unsigned 32-bit integer):

dwElapsed := (GetTickCount() - m_dwLastFlashCheck);
if (dwElapsed > 2000) then
    begin
    m_dwLastFlashCheck := GetTickCount();
    DoSomething();
    end;

it seems natural to define a "constant" as in:

RATE_FLASH: DWORD   = 2000;
// ...
if (dwElapsed > RATE_FLASH) then
// etc
Community
  • 1
  • 1
AlainD
  • 5,413
  • 6
  • 45
  • 99
  • Related, [delphi string leak](http://stackoverflow.com/q/5423329/576719). – LU RD Dec 07 '15 at 14:25
  • 1
    In your last question, the use of a typed constant is not needed. A true constant,`RATE_FLASH = 2000`, is sufficient. The compiler will usually find the correct translation. In some cases, you can use `RATE_FLASH = DWORD(2000)` to make it clearer. – LU RD Dec 07 '15 at 14:33
  • @LURD: Right you are! I'll use your suggested `RATE_FLASH = DWORD(2000)` in future as this seems both clear and gives a true constant. – AlainD Dec 07 '15 at 14:45

1 Answers1

4

Such constants are located in the executable image. As such, they are allocated when the module loads, deallocated when the module unloads and so they cannot be leaked.

Your constants are not the problem. You clearly have a badly decoded stack trace. If you could use madExcept, for example, to decode the stack traces then I suspect you'd get better stack traces. It's also plausible that the bad stack trace is due to an out of date map file.

The bottom line is that you should never have a data address as a return address on the stack. So, the stack trace must be erroneous.


Now, you also link to references that advise against using typed constants. But you are reading those references incorrectly. Typed constants are a perfectly valid approach in many situations.

What is questionable are assignable typed constants – any feature whose name is an oxymoron should be regarded with extreme suspicion. It turns out that assignable typed constants only exist through an accident of implementation. When typed constants were introduced, they could not be placed in read only memory because the systems of the day did not support memory protection. When memory protection was introduced, the compiler was enhanced to support two modes of typed constant: read-only and assignable. Please do shun assignable typed constants, but read-only typed constants are quite reasonable.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • OK, will look into using madExcept. Have it installed but need to remind myself how to use it. – AlainD Dec 07 '15 at 13:39
  • You need to get FastMM to use its stack trace functions. IIRC. – David Heffernan Dec 07 '15 at 13:55
  • You're right, but AFAICS I have configured FastMM4 to use its stack trace functions by defining 'FullDebugMode' and 'RawStackTraces' in the .inc file for FastMM4. By enabling these options and the detailed map file, FastMM4 reports the trace as reported in the question eg. '[Main][Main][EXAMPLE_TYPED_CONSTANT1]'. – AlainD Dec 07 '15 at 14:29
  • I reverted the edit since it asks a new question. The question here was clear: *Can typed constants be a source of memory leaks?* I have answered that. We went through this at another recent question of yours. I think it's not fully clear to you that this site is about answering the question that was asked, not about solving the problem behind that question. I answered your question, and now it's for you to continue tracking down the defect with your new knowledge. – David Heffernan Dec 07 '15 at 15:02
  • You're right that assignable type constants are to be avoided. That was the sense in which I read those links and concluded "they should be avoided", but I do see that this issue is more nuanced. Thanks for your input. – AlainD Dec 07 '15 at 15:09
  • I suppose my point is that typed constants are not to be avoided and are in fact to be encouraged in my situations. Here you can use a literal and that's often better, but if you need to take an address, or the type is more complex and a literal is not possible, then typed constants are a very good thing. – David Heffernan Dec 07 '15 at 15:16