FlexeLint warning (assert seems ignored)

  • Thread starter Martin Herbert Dietze
  • Start date
M

Martin Herbert Dietze

Hello,

consider this code:

| /* warning613.c */
| #include <assert.h>
| #include <string.h>
|
| size_t
| myStrLen(char const* s)
| {
| assert (s != NULL);
| return strlen (s);
| }

Now when I run flexelint like this:

| lint +v -i`pwd`/flint/ansi -u warning613.c

(./flint/ansi contains the ansi headers provided with flint,
the -u suppresses the warning about myStrLen() not being
referenced)

I now get this diagnosis message:

| FlexeLint for C/C++ (Unix) Vers. 8.00v, Copyright Gimpel Software 1985-2006
|
| --- Module: warning613.c (C)--- Module: warning613.c (C)
|
| _
| return strlen (s);
| warning613.c 8 Warning 668: Possibly passing a null pointer to function
| 'strlen(const char *)', arg. no. 1 [Reference: file
| warning613.c: line 7]
| warning613.c 7 Info 831: Reference cited in prior message

Of course I could put an "if (s != NULL)" into the code, but
since this example is taken from some larger piece of code and
s not being NULL is actually a precondition to the real
function, this would seem an unnecessary "lint-happy". When
checking the code with splint this error is not reported.

Any idea?

Cheers,

Martin
 
S

santosh

Martin said:
Hello,

consider this code:

| /* warning613.c */
| #include <assert.h>
| #include <string.h>
|
| size_t
| myStrLen(char const* s)
| {
| assert (s != NULL);
| return strlen (s);
| }

Now when I run flexelint like this:

| lint +v -i`pwd`/flint/ansi -u warning613.c

(./flint/ansi contains the ansi headers provided with flint,
the -u suppresses the warning about myStrLen() not being
referenced)

I now get this diagnosis message:

| FlexeLint for C/C++ (Unix) Vers. 8.00v, Copyright Gimpel Software 1985-2006
|
| --- Module: warning613.c (C)--- Module: warning613.c (C)
|
| _
| return strlen (s);
| warning613.c 8 Warning 668: Possibly passing a null pointer to function
| 'strlen(const char *)', arg. no. 1 [Reference: file
| warning613.c: line 7]
| warning613.c 7 Info 831: Reference cited in prior message

Of course I could put an "if (s != NULL)" into the code, but
since this example is taken from some larger piece of code and
s not being NULL is actually a precondition to the real
function, this would seem an unnecessary "lint-happy". When
checking the code with splint this error is not reported.

Any idea?

Cheers,

Martin

This is probably a FlexeLint related issue rather than an ISO standard
C related one. Specific tools are considered off-topic here. Maybe you
should ask in a forum for your tool, or perhaps try contacting it's
author/s?
 
J

Jens Thoms Toerring

Martin Herbert Dietze said:
consider this code:
| /* warning613.c */
| #include <assert.h>
| #include <string.h>
|
| size_t
| myStrLen(char const* s)
| {
| assert (s != NULL);
| return strlen (s);
| }
Now when I run flexelint like this:
| lint +v -i`pwd`/flint/ansi -u warning613.c
(./flint/ansi contains the ansi headers provided with flint,
the -u suppresses the warning about myStrLen() not being
referenced)
I now get this diagnosis message:
| FlexeLint for C/C++ (Unix) Vers. 8.00v, Copyright Gimpel Software 1985-2006
|
| --- Module: warning613.c (C)--- Module: warning613.c (C)
|
| _
| return strlen (s);
| warning613.c 8 Warning 668: Possibly passing a null pointer to function
| 'strlen(const char *)', arg. no. 1 [Reference: file
| warning613.c: line 7]
| warning613.c 7 Info 831: Reference cited in prior message
Of course I could put an "if (s != NULL)" into the code, but
since this example is taken from some larger piece of code and
s not being NULL is actually a precondition to the real
function, this would seem an unnecessary "lint-happy". When
checking the code with splint this error is not reported.

Well, it's just a warning - and assert() does only protects you
(for some questionable way of protection) against 's' being NULL
as long as NDEBUG isn't defined before the last inclusion of
<assert.h>, if it's defined (as it typically will in production
code) assert() becomes a NOP and nothing keeps you anymore from
passing a NULL pointer to strlen(), so the warning looks rather
reasonable to me.
Regards, Jens
 
D

Dave Hansen

Hello,

consider this code:
[...]
| size_t
| myStrLen(char const* s)
| {
| assert (s != NULL);
| return strlen (s);
| }
[...]
I now get this diagnosis message:
[...]
| return strlen (s);
| warning613.c 8 Warning 668: Possibly passing a null pointer to function
| 'strlen(const char *)', arg. no. 1 [Reference: file
| warning613.c: line 7]

Not really a C question. You could try the forums at www.gimpel.com.

What I think they will tell you is this: because you are testing for
NULL (in the assert), value-tracking will include the possiblility of
a null pointer. If lint doesn't recognize that the function called
when the assert fails does not return, and nothing modifies s before
the call to strlen, you may be calling strlen with a null pointer. As
far as lint is concerned, anyway.

If you #define NDEBUG, the lint warning will probably go away. If you
tell lint that the function called when s is NULL doesn't return, the
warning should go away as well. The option

-function(exit,assert_fail)

will tell lint that the function assert_fail does not return when
called. Substitute the name of the function called by the assert
macro when the condition fails.

HTH,
-=Dave
 
S

Stephen Sprunk

Martin Herbert Dietze said:
| size_t
| myStrLen(char const* s)
| {
| assert (s != NULL);
| return strlen (s);
| } ....

Of course I could put an "if (s != NULL)" into the code, but
since this example is taken from some larger piece of code and
s not being NULL is actually a precondition to the real
function, this would seem an unnecessary "lint-happy". When
checking the code with splint this error is not reported.

You don't _know_ that someone won't call your function with a null argument;
all you know is that it's in the documentation that it's illegal or that the
current code that calls it won't (er, shouldn't) do that. Lint obviously
don't "know" that either.

However, such "knowledge" generally tends to be false over time. You should
put the "if" in and handle the error gracefully. assert() is not an
error-handling mechanism; it's a bug-finding one. When you define NDEBUG,
your errors still need to be handled -- and errors will occur eventually,
after enough people "maintain" the code.

S
 
J

james.widman

consider this code:
[...]
| size_t
| myStrLen(char const* s)
| {
| assert (s != NULL);
| return strlen (s);
| }
[...]
I now get this diagnosis message:
[...]
| return strlen (s);
| warning613.c 8 Warning 668: Possibly passing a null pointer to function
| 'strlen(const char *)', arg. no. 1 [Reference: file
| warning613.c: line 7]

Not really a C question. You could try the forums atwww.gimpel.com.

What I think they will tell you is this: because you are testing for
NULL (in the assert), value-tracking will include the possiblility of
a null pointer. If lint doesn't recognize that the function called
when the assert fails does not return, and nothing modifies s before
the call to strlen, you may be calling strlen with a null pointer. As
far as lint is concerned, anyway.

If you #define NDEBUG, the lint warning will probably go away. If you
tell lint that the function called when s is NULL doesn't return, the
warning should go away as well. The option

-function(exit,assert_fail)

will tell lint that the function assert_fail does not return when
called. Substitute the name of the function called by the assert
macro when the condition fails.

HTH,
-=Dave

I agree with this; I only want to mention that section 9.2.1 of the
Flexelint manual ("The assert remedy") further elaborates on this
point.

James Widman
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,767
Messages
2,569,570
Members
45,045
Latest member
DRCM

Latest Threads

Top