frododot
frododot

Reputation: 127

printf format string lint warning

I'm stuck fixing ancient code, and here is today's issue:

output_file_status = fprintf ( data_file, "%03d%08s%+014.2f%06.3f%",
    LongValue, CharStarValue, Double1, Double2 );

Lint32 produces: Lint32 results in “malformed format string”

1) Do you all agree the format string can not end in a % sign? I don't believe a standalone % has meaning.

2) When I either remove the trailing %, or append an additional %, I still get the same warning.

This is using the Oracle Pro*C compiler (so the CharStarValue is actually a (char*)VarChar.arr ).

Upvotes: 1

Views: 1642

Answers (2)

chux
chux

Reputation: 153517

Taking it piece by piece:

"%03d" expects an int. OP supplies a LongValue. With a long, specifier should be "%03ld".

"%08s" expects a pointer to char. OP supplies CharStarValue. OK. But the "0" in the specifier is undefined behavior for a %s. Recommend "%8s"

"%+014.2f" expects a double. OK. Flags '+', '0' are OK.

"%06.3f" expects a double. OK. Flags '+', '0' are OK.

"%" should have something after it else behavior is undefined. Recommend removal or "%%".


To OP's 2 points

1 A proper format should not end with a lone %, but may end with paired %%s.
A standalone % introduces "If a conversion specification is invalid, the behavior is undefined" C11 7.21.6.1 9.

2 To get rid of all warnings, try "%03ld%8s%+014.2f%06.3f".

Upvotes: 2

Greg Hewgill
Greg Hewgill

Reputation: 993243

Yes, you are correct that % by itself at the end is an error. It should be %% to produce one literal % in the formatted output.

It might be that your linter is also complaining about the use of %03d with a long value. That should be %03ld.

Upvotes: 2

Related Questions