Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2016-10

Checking the validity of Format and friends at compile-time

7 messages · 6 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Michalis Kamburelis

Hi,

I'm wondering if there is a tool that checks the correctness of calls to Format and friends (like Exception.CreateFmt) in your code. Or does someone plan to write one, as an external tool (like a "lint") or inside the FPC compiler:)

For example, the call

Format('%s', [123])

is guaranteed to result in an nothing at
compile-time detects or warns about it.

Sure, it's not possible to check all cases of Format usage, as you can construct the Format pattern (or list of arguments) at runtime. You can also replace , such tool would be
useful since (at least in my code) the majority or Format calls have constant strings and could be checked at parse time.

The tool would have to know which routines have Format-like parameters (and at which positions), to capture Format, and Exception.CreateFmt (and I have a couple of more in my own units). They could be marked in the source code, by some special directive or a special comment, or the checking tool should just know their names.

Such tool seems useful for me. It would at least catch *some* blatant errors, that otherwise sleep undetected until runtime. E.g. today I have a bugreport that user observed an EConvertError in my program (unfortunately, he cannot write more exactly what is the message, or send a screenshot...). I suspect the bug is in one of my Format or EXxx.CreateFmt calls, but I have a lot of them. Most of them have constant pattern (and a list of arguments with size and types known at compile-time), so it should be possible to run some kind of "lint" on my code... except I don't have any:)

Does anyone know of such a tool?

If you don't have a good answer, I may implement it myself:) I'd like to use fcl-passrc for it, but so far it fails to parse my real-life code in Castle Game Engine:) I submitted a couple of bugreports about it today.

Regards,
Michalis

Reply by email

Sven Barth
to Michalis Kamburelis

Am 05.10.2016 04:33 schrieb "Michalis Kamburelis" <

Show quoted text 8 lines
: Hi, I'm wondering if there is a tool that checks the correctness of calls to Format and friends (like Exception.CreateFmt) in your code. Or does someone plan to write one, as an external tool (like a "lint") or inside the FPC compiler:)

I don't know of any tool, but something like this definitely wouldn't become part of the compiler as that would mean an unnecessarily tight coupling between compiler and RTL not to mention that user code that uses "array of const" wouldn't necessarily benefit from it.

Regards,
Sven

Reply by email

Maciej Izak
to Michalis Kamburelis: I'm wondering if there is a tool that checks the correctness of calls to Format and…

2016-10-05 4:32 GMT+02:00 Michalis Kamburelis :

For example, the call Format('%s', [123])

I have a small hint (instead of answer). We have in mORMot / NewPascal in SynCommons module nice function which works perfect in most of cases:

FormatUTF8('%', [123], []); // same string '%' works for both: integer and
string values
FormatUTF8('%', ['123'], []);

Documentation:
http://synopse.info/files/html/api-1.18/SynCommons.html#FORMATUTF8

Best regards, Maciej Izak

Reply by email

Michael Schnell
to Sven Barth: Am 05.10.2016 04:33 schrieb "Michalis Kamburelis" < I don't know of any tool, but…
Sven Barth wrote
something like this definitely wouldn't become part of the compiler as that would mean an unnecessarily tight coupling between compiler and RTL not to mention that user code that uses "array of const" wouldn't necessarily benefit from it.

GNU C does check this when using printf() and friends, and rather obviously the "array of const" is modeled after the C ellipse notation.

-Michael

Reply by email

Michalis Kamburelis
to Maciej Izak: 2016-10-05 4:32 GMT+02:00 Michalis Kamburelis : I have a small hint (instead of answer).…

2016-10-05 9:00 GMT+02:00 Maciej Izak :

Show quoted text 15 lines
2016-10-05 4:32 GMT+02:00 Michalis Kamburelis : > > For example, the call > > Format('%s', [123]) I have a small hint (instead of answer). We have in mORMot / NewPascal in SynCommons module nice function which works perfect in most of cases: FormatUTF8('%', [123], []); // same string '%' works for both: integer and string values FormatUTF8('%', ['123'], []);

That's a cool improvement. No need to write the type, so one less thing that can go wrong:) I seldom use non-standard formats anyway (like %g instead of %f for floats).

Still, you can use an invalid number of arguments for FormatUTF8. So you still have this uncomfortable feeling that "it's only checked at runtime, while it could be checked earlier at lint / compile phase" :)

I'm leaning toward implementing a simple pascal-lint tool myself, using the fcl-passrc. But to make it really useful on my real code, I'll need some fixes to fcl-passrc first:)

Regards,
Michalis

Reply by email

Marco van de Voort
to Michael Schnell: GNU C does check this when using printf() and friends, and rather obviously the "array of…

In our previous episode, Michael Schnell said:

> RTL not to mention that user code that uses "array of const" wouldn't > necessarily benefit from it. GNU C does check this when using printf() and friends, and rather obviously the "array of const" is modeled after the C ellipse notation.

But array of const is safe, and C's isn't, which is why C compilers routinely check it.

Reply by email

Santiago A.
to Michalis Kamburelis: 2016-10-05 9:00 GMT+02:00 Maciej Izak : That's a cool improvement. No need to write the…
Michalis Kamburelis wrote 16 lines
2016-10-05 9:00 GMT+02:00 Maciej Izak : > 2016-10-05 4:32 GMT+02:00 Michalis Kamburelis : >> For example, the call >> >> Format('%s', [123]) > > I have a small hint (instead of answer). We have in mORMot / NewPascal in > SynCommons module nice function which works perfect in most of cases: > > FormatUTF8('%', [123], []); // same string '%' works for both: integer and > string values > FormatUTF8('%', ['123'], []); > That's a cool improvement. No need to write the type, so one less thing that can go wrong:) I seldom use non-standard formats anyway (like %g instead of %f for floats).

I don't agree. You are asking for a compile time check, but now you accept skipping run time type check doing a automatic type conversion. Things can go as wrong as with classic format but, without runtime error or exception, hunting bugs is more difficult. I support your first idea: Compile time check.

I haven't understand very well whether Sven Barth's reluctance is a matter of taste or whether there are serious technical reasons. If there are not severe design drawbacks, I would go for it. I love compile time checks. The more, the better.

Saludos Santiago A.

Reply by email