User avatar
HermannSW
Posts: 4603
Joined: Fri Jul 22, 2016 9:09 pm
Location: Eberbach, Germany
Contact: Website Twitter YouTube

[SOLVED] What is wrong with Raspberry struct timespec and splint?

Sun Aug 08, 2021 6:44 am

I did install splint.
I used it to validate this code initializing a "struct Person" variable without issues:
https://www.delftstack.com/howto/c/c-initialize-struct/

Code: Select all

pi@raspberrypi400:~ $ splint person.c 
Splint 3.1.2 --- 05 Sep 2017

Finished checking --- no warnings
pi@raspberrypi400:~ $ 

Now my "struct timespec" code gets compiled without any warnings although I specified many warning options:

Code: Select all

pi@raspberrypi400:~ $ gcc cgt.c -Wall -Wextra -pedantic -o cgt
pi@raspberrypi400:~ $ ./cgt 
 1241ns
pi@raspberrypi400:~ $ 

This is "cgt.c":

Code: Select all

#include <stdio.h>
#include <time.h>

int main ()
{
  struct timespec t0 = { .tv_sec=0, .tv_nsec=0 };
  struct timespec t1 = { .tv_sec=0, .tv_nsec=0 };

  clock_gettime(CLOCK_REALTIME, &t0);
  clock_gettime(CLOCK_REALTIME, &t1);

  printf(" %ldns\n", (t1.tv_sec-t0.tv_sec) * 1000000000 + t1.tv_nsec - t0.tv_nsec);

  return 0;
}

Running splint results in warnings that all seem to indicate that splint has no idea of "struct timespec" definition:

Code: Select all

pi@raspberrypi400:~ $ splint cgt.c 
Splint 3.1.2 --- 05 Sep 2017

cgt.c: (in function main)
cgt.c:6:24: Initializer block used for t0 where struct timespec is expected:
               { <error>, <error> }
  Types are incompatible. (Use -type to inhibit warning)
cgt.c:7:24: Initializer block used for t1 where struct timespec is expected:
               { <error>, <error> }
cgt.c:9:3: Unrecognized identifier: clock_gettime
  Identifier used in code has not been declared. (Use -unrecog to inhibit
  warning)
cgt.c:9:17: Unrecognized identifier: CLOCK_REALTIME

Finished checking --- 4 code warnings
pi@raspberrypi400:~ $ 

How can splint be fixed (according "man clock_gettime" I only need to include "<time.h>")?
Is there another C linter available for Raspberry Pi OS?
Last edited by HermannSW on Sun Aug 08, 2021 12:17 pm, edited 1 time in total.
https://github.com/Hermann-SW/memrun
https://stamm-wilbrandt.de/2wheel_balancing_robot
https://stamm-wilbrandt.de/en#raspcatbot
https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter
https://stamm-wilbrandt.de/en/Raspberry_camera.html

User avatar
jahboater
Posts: 7370
Joined: Wed Feb 04, 2015 6:38 pm
Location: Wonderful West Dorset

Re: What is wrong with Raspberry struct timespec and splint?

Sun Aug 08, 2021 10:04 am

HermannSW wrote:
Sun Aug 08, 2021 6:44 am
How can splint be fixed (according "man clock_gettime" I only need to include "<time.h>")?
Is there another C linter available for Raspberry Pi OS?
Compiler diagnostics have improved so much over the years that lint is obsolete.
Furthermore, GCC supports the latest standards (including draft support for future standards such as C2x), whereas splint clearly does not. In fact splint doesn't appear to have any options specifying the C version to check against.

These days I use this in the makefile (with the latest version of the GCC):

Code: Select all

LINT = -Wall -Wextra -Wconversion -Wuninitialized -Wunused -Wcast-qual -Wcast-align=strict \
       -Wpacked -Wduplicated-branches -Wduplicated-cond -Wpointer-arith -Wnested-externs \
       -Wfloat-conversion -Wsign-conversion -Warith-conversion -Wnarrowing -Wsign-compare \
       -Winline -Woverflow -Wmissing-include-dirs -Wredundant-decls -Wunused-macros -fanalyzer \
       -Wformat-truncation=2 -Woverlength-strings -Wdisabled-optimization -Wnormalized \
       -Wformat-overflow=1 -Wformat=2 -Wrestrict -Wshift-overflow=2 -Wunsafe-loop-optimizations \
       -Wnull-dereference -Wstringop-truncation -Wstringop-overflow=4 -Winit-self -Wmultichar \
       -Wstrict-prototypes -Wreturn-local-addr -Wlogical-op -Wundef -Wwrite-strings \       
       -Wformat-signedness -Wstrict-overflow=2 -Wunused-const-variable=2 -Wmissing-noreturn \
       -Warray-bounds=2 -Wdiscarded-qualifiers -Wstrict-aliasing=3 -Wdouble-promotion \
       -Wunsafe-loop-optimizations -Wmaybe-uninitialized -Wtrampolines  
Then something like:

Code: Select all

lint: prog.c
  gcc -O3 $(LINT) prog.c -o /dev/null
Notes
1) -O3 does a deeper analysis and can provide more accurate diagnostics for things like uninitialized variables.
2) -fanalyzer is available in recent versions of GCC and takes ages!
3) -Wall and -Wextra do not include all the warning options ...
4) the important options are in the first line of the above and IMHO should be used for all compilations

For program correctness you could/should look at the run time sanitizers provided by GCC:

Code: Select all

#
#  Sanitizers
#  -fsanitize=hwaddress
#
ASAN = -fno-sanitize-recover=all -fsanitize=address -fsanitize=undefined

SAN = $(ASAN)                            \
      -fsanitize-address-use-after-scope \
      -fsanitize=leak                    \
      -fsanitize=bounds                  \
      -fsanitize=bounds-strict           \
      -fsanitize=integer-divide-by-zero  \
      -fsanitize=float-divide-by-zero    \
      -fsanitize=float-cast-overflow     \
      -fsanitize=unreachable             \
      -fsanitize=vla-bound               \
      -fsanitize=null                    \
      -fsanitize=signed-integer-overflow \
      -fsanitize=object-size             \
      -fsanitize=bool                    \
      -fsanitize=enum                    \
      -fsanitize=return                  \
      -fsanitize=shift                   \
      -fsanitize=shift-exponent          \
      -fsanitize=shift-base              \
      -fsanitize=alignment               \
      -fsanitize=builtin                 \
      -fsanitize=pointer-subtract        \
      -fsanitize=pointer-overflow        \
      -fsanitize=pointer-compare
some of these may be the default.

In general, you get the best diagnostics with the latest version of GCC (currently 11.2)

When -fanalyzer finds a problem you get a beautifully presented tree diagram showing the control flow path all the way from the start of main() to the problem. It shows what decisions were taken in the code that could lead to the error. You can see why it takes extra time!
As far as I know, no "lint" or static checker program can do things like that.

Another checker worth running is valgrind.
This takes any program and runs it with extensive checks on each and every instruction and many of the library calls. It is slower than the sanitizers of course.

User avatar
HermannSW
Posts: 4603
Joined: Fri Jul 22, 2016 9:09 pm
Location: Eberbach, Germany
Contact: Website Twitter YouTube

Re: [SOLVED] What is wrong with Raspberry struct timespec and splint?

Sun Aug 08, 2021 12:04 pm

Thanks for the very detailed list of options -- I know valgrind from debugging difficult memory issues at day job.

32bit Raspberry Pi OS gcc is version 8.3.0, and does not know "-fanalyze".
I also changed the other unknown option according gcc hint:

Code: Select all

gcc: error: unrecognized command line option ‘-Warith-conversion’; did you mean ‘-Wint-conversion’?
And I added "-pedantic" which I often used.

This is LINT definition that works:

Code: Select all

pi@raspberrypi400:~ $ tail -13 ~/.bashrc | head -11
LINT="-Wall -Wextra -Wconversion -Wuninitialized -Wunused -Wcast-qual -Wcast-align=strict \
       -Wpacked -Wduplicated-branches -Wduplicated-cond -Wpointer-arith -Wnested-externs \
       -Wfloat-conversion -Wsign-conversion -Wint-conversion -Wnarrowing -Wsign-compare \
       -Winline -Woverflow -Wmissing-include-dirs -Wredundant-decls -Wunused-macros \
       -Wformat-truncation=2 -Woverlength-strings -Wdisabled-optimization -Wnormalized \
       -Wformat-overflow=1 -Wformat=2 -Wrestrict -Wshift-overflow=2 -Wunsafe-loop-optimizations \
       -Wnull-dereference -Wstringop-truncation -Wstringop-overflow=4 -Winit-self -Wmultichar \
       -Wstrict-prototypes -Wreturn-local-addr -Wlogical-op -Wundef -Wwrite-strings \
       -Wformat-signedness -Wstrict-overflow=2 -Wunused-const-variable=2 -Wmissing-noreturn \
       -Warray-bounds=2 -Wdiscarded-qualifiers -Wstrict-aliasing=3 -Wdouble-promotion \
       -Wunsafe-loop-optimizations -Wmaybe-uninitialized -Wtrampolines -pedantic"
pi@raspberrypi400:~ $ 

And this is "lint" alias:

Code: Select all

pi@raspberrypi400:~ $ tail -1 ~/.bashrc
alias lint="gcc -O3 $LINT -o /dev/null"
pi@raspberrypi400:~ $ 

Running "lint" for cgt.c complained on "main":

Code: Select all

pi@raspberrypi400:~ $ lint cgt.c 
cgt.c:4:5: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
 int main ()
     ^~~~
pi@raspberrypi400:~ $

Adding argc and argv complained on unused variables.
This little change silences "lint":

Code: Select all

pi@raspberrypi400:~ $ head -6 cgt.c | tail -3
#define ATTR(a)  __attribute__((a)) 

int main (ATTR(unused) int argc, ATTR(unused) char *argv[])
pi@raspberrypi400:~ $ 

Code: Select all

pi@raspberrypi400:~ $ lint cgt.c 
pi@raspberrypi400:~ $ 

P.S:
With this "lint" no initialization assignments to t0 and t1 are needed
(commenting out a call to "clock_gettime()" makes lint complain on uninitialized variable).

Code: Select all

pi@raspberrypi400:~ $ lint cgt.c 
pi@raspberrypi400:~ $ cat cgt.c 
#include <stdio.h>
#include <time.h>

#define ATTR(a)  __attribute__((a)) 

int main (ATTR(unused) int argc, ATTR(unused) char *argv[])
{
  struct timespec t0, t1;

  clock_gettime(CLOCK_REALTIME, &t0);
  clock_gettime(CLOCK_REALTIME, &t1);

  printf(" %ldns\n", (t1.tv_sec-t0.tv_sec) * 1000000000 + t1.tv_nsec - t0.tv_nsec);

  return 0;
}
pi@raspberrypi400:~ $ 

P.P.S:
I just linted my latest gmplib Gist:
https://gist.github.com/Hermann-SW/1f57 ... 40a85de254

After adding "-lgmp" lint is fine with the code:

Code: Select all

pi@raspberrypi400:~ $ lint cycle_id.c -lgmp
pi@raspberrypi400:~ $ 
https://github.com/Hermann-SW/memrun
https://stamm-wilbrandt.de/2wheel_balancing_robot
https://stamm-wilbrandt.de/en#raspcatbot
https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter
https://stamm-wilbrandt.de/en/Raspberry_camera.html

User avatar
HermannSW
Posts: 4603
Joined: Fri Jul 22, 2016 9:09 pm
Location: Eberbach, Germany
Contact: Website Twitter YouTube

Re: [SOLVED] What is wrong with Raspberry struct timespec and splint?

Sun Aug 08, 2021 12:48 pm

Useful, lint identified an issue on my 2nd last Gist:

Code: Select all

pi@raspberrypi400:~ $ lint fn.c -lgmp
fn.c: In function ‘main’:
fn.c:43:7: warning: conversion to ‘long unsigned int’ from ‘long int’ may change the sign of the result [-Wsign-conversion]
   i = atol(argv[3]);
       ^~~~
pi@raspberrypi400:~ $ 

Just updated the Gist so that lint is fine:
https://gist.github.com/Hermann-SW/eb4a ... b1708aac1f

Code: Select all

pi@raspberrypi400:~ $ lint fn.c -lgmp
pi@raspberrypi400:~ $ 
https://github.com/Hermann-SW/memrun
https://stamm-wilbrandt.de/2wheel_balancing_robot
https://stamm-wilbrandt.de/en#raspcatbot
https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter
https://stamm-wilbrandt.de/en/Raspberry_camera.html

User avatar
jahboater
Posts: 7370
Joined: Wed Feb 04, 2015 6:38 pm
Location: Wonderful West Dorset

Re: [SOLVED] What is wrong with Raspberry struct timespec and splint?

Sun Aug 08, 2021 5:00 pm

HermannSW wrote:
Sun Aug 08, 2021 12:04 pm
I also changed the other unknown option according gcc hint:

Code: Select all

gcc: error: unrecognized command line option ‘-Warith-conversion’; did you mean ‘-Wint-conversion’?
Sorry about that, -Warith-conversion came in with GCC 10
HermannSW wrote:
Sun Aug 08, 2021 12:04 pm
Running "lint" for cgt.c complained on "main":

Code: Select all

pi@raspberrypi400:~ $ lint cgt.c 
cgt.c:4:5: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
 int main ()
     ^~~~
pi@raspberrypi400:~ $
Adding argc and argv complained of unused variables.
I suggest using:

Code: Select all

int main( void )
then you don't have to worry about the unused argc and argv!

User avatar
HermannSW
Posts: 4603
Joined: Fri Jul 22, 2016 9:09 pm
Location: Eberbach, Germany
Contact: Website Twitter YouTube

Re: What is wrong with Raspberry struct timespec and splint?

Thu Aug 12, 2021 3:07 pm

jahboater wrote:
Sun Aug 08, 2021 10:04 am
Compiler diagnostics have improved so much over the years that lint is obsolete.
Furthermore, GCC supports the latest standards (including draft support for future standards such as C2x), whereas splint clearly does not. In fact splint doesn't appear to have any options specifying the C version to check against.
While lint might be obsolete, my older son pointed to clang-tidy (sudo apt install clang-tidy).
While your "lint" of using tons of "$LINT" gcc compile options works, it did report 0 issues with my analyze.c:
https://gist.github.com/Hermann-SW/83de ... 641c26c590

First I did not trust the reported "use garbage" messages, but the analysis was correct, for n<=4 access to M[4] was accessing uninitialized values because of "for(x=0; x<n; ++x) M[x]=n;" initialization. I really hope that "-fanalyze" for gcc that supports it would uncover that issue as well.

I did silence all messages clang-tidy reported, and it was a lot of work. Some are for readability (don't use else after a return), some on incorrect order of includes -- I never realized that could be an issue.

I was surprised on atoi() warnings and hint to use strtol instead.

Use of bzero() was reported as obsolete and hint to use memset() instead was given.

At many locations I used a single statement after a for loop, and I got advised to use braces around.

Below is complete output of clang-tidy, with 95 warnings, with 59 suppressed in non-user code that still makes 36 warnings I was responsible for. See revision 5 of the Gist for all the changes I had to do to, that now result in no user-code warnings:

Code: Select all

pi@raspberrypi400:~ $ clang-tidy analyze.c -checks=* --
59 warnings generated.
Suppressed 59 warnings (59 in non-user code).
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
pi@raspberrypi400:~ $ 

This is previous version with the 36 user-code warnings I just eliminated, shown here to get an idea:

Code: Select all

pi@raspberrypi400:~/old $ clang-tidy analyze.c -checks=* --
95 warnings generated.
/home/pi/old/analyze.c:2:1: warning: #includes are not sorted properly [llvm-include-order]
#include <stdio.h>
^        ~~~~~~~~~
         <assert.h>
/home/pi/old/analyze.c:19:3: warning: do not use 'else' after 'return' [readability-else-after-return]
  else
  ^~~~
/home/pi/old/analyze.c:34:5: warning: do not use 'else' after 'return' [readability-else-after-return]
    else 
    ^~~~~
/home/pi/old/analyze.c:34:9: warning: statement should be inside braces [readability-braces-around-statements]
    else 
        ^
         {
/home/pi/old/analyze.c:62:10: warning: 'atoi' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtol' instead [cert-err34-c]
  assert(atoi(argv[1]) >= 0);
         ^
/home/pi/old/analyze.c:63:10: warning: 'atoi' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtol' instead [cert-err34-c]
  assert(atoi(argv[2]) >= 0);
         ^
/home/pi/old/analyze.c:64:13: warning: 'atoi' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtol' instead [cert-err34-c]
  n=(unsig) atoi(argv[1]);
            ^
/home/pi/old/analyze.c:65:13: warning: 'atoi' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtol' instead [cert-err34-c]
  a=(unsig) atoi(argv[2]);
            ^
/home/pi/old/analyze.c:71:3: warning: The bzero() function is obsoleted by memset() [clang-analyzer-security.insecureAPI.bzero]
  bzero(A, sizeof(unsig)*n);
  ^
/home/pi/old/analyze.c:71:3: note: The bzero() function is obsoleted by memset()
/home/pi/old/analyze.c:72:21: warning: statement should be inside braces [hicpp-braces-around-statements]
  for(x=0; x<n; ++x)
                    ^
                     {
/home/pi/old/analyze.c:75:21: warning: statement should be inside braces [readability-braces-around-statements]
  for(x=0; x<n; ++x)
                    ^
                     {
/home/pi/old/analyze.c:84:11: warning: statement should be inside braces [hicpp-braces-around-statements]
      else
          ^
           {
/home/pi/old/analyze.c:88:21: warning: statement should be inside braces [google-readability-braces-around-statements]
  for(x=1; x<l; ++x)
                    ^
                     {
/home/pi/old/analyze.c:89:5: warning: 2nd function call argument is an uninitialized value [clang-analyzer-core.CallAndMessage]
    printf(fmt" ", L[x]);
    ^
/home/pi/old/analyze.c:69:5: note: Storing uninitialized value
  L=malloc(sizeof(unsig)*1000); assert(L);
    ^
/home/pi/old/analyze.c:72:12: note: Assuming 'x' is < 'n'
  for(x=0; x<n; ++x)
           ^
/home/pi/old/analyze.c:72:3: note: Loop condition is true.  Entering loop body
  for(x=0; x<n; ++x)
  ^
/home/pi/old/analyze.c:72:12: note: Assuming 'x' is < 'n'
  for(x=0; x<n; ++x)
           ^
/home/pi/old/analyze.c:72:3: note: Loop condition is true.  Entering loop body
  for(x=0; x<n; ++x)
  ^
/home/pi/old/analyze.c:72:12: note: Assuming 'x' is >= 'n'
  for(x=0; x<n; ++x)
           ^
/home/pi/old/analyze.c:72:3: note: Loop condition is false. Execution continues on line 75
  for(x=0; x<n; ++x)
  ^
/home/pi/old/analyze.c:75:3: note: Loop condition is true.  Entering loop body
  for(x=0; x<n; ++x)
  ^
/home/pi/old/analyze.c:76:9: note: Assuming the condition is true
    if (A[x]==0)
        ^
/home/pi/old/analyze.c:76:5: note: Taking true branch
    if (A[x]==0)
    ^
/home/pi/old/analyze.c:79:11: note: Assuming 'c' is equal to 'l'
      if (c==l)
          ^
/home/pi/old/analyze.c:79:7: note: Taking true branch
      if (c==l)
      ^
/home/pi/old/analyze.c:75:3: note: Loop condition is true.  Entering loop body
  for(x=0; x<n; ++x)
  ^
/home/pi/old/analyze.c:76:9: note: Assuming the condition is false
    if (A[x]==0)
        ^
/home/pi/old/analyze.c:76:5: note: Taking false branch
    if (A[x]==0)
    ^
/home/pi/old/analyze.c:75:3: note: Loop condition is false. Execution continues on line 88
  for(x=0; x<n; ++x)
  ^
/home/pi/old/analyze.c:88:3: note: Loop condition is true.  Entering loop body
  for(x=1; x<l; ++x)
  ^
/home/pi/old/analyze.c:89:5: note: 2nd function call argument is an uninitialized value
    printf(fmt" ", L[x]);
    ^
/home/pi/old/analyze.c:91:21: warning: statement should be inside braces [readability-braces-around-statements]
  for(x=0; x<n; ++x)
                    ^
                     {
/home/pi/old/analyze.c:104:17: warning: statement should be inside braces [hicpp-braces-around-statements]
    if (M[x]>mm)  mm=M[x];
                ^
                 {
/home/pi/old/analyze.c:106:20: warning: statement should be inside braces [hicpp-braces-around-statements]
    if (L[A[x]]>ml)  ml=L[A[x]];
                   ^
                    {
/home/pi/old/analyze.c:108:26: warning: statement should be inside braces [hicpp-braces-around-statements]
    if (L[A[x]]+M[x]>mlm)  mlm=L[A[x]]+M[x];
                         ^
                          {
/home/pi/old/analyze.c:115:32: warning: The right operand of '+' is a garbage value [clang-analyzer-core.UndefinedBinaryOperatorResult]
  printf("lm1 "fmt"\n", L[A[1]]+M[1]);
                               ^
/home/pi/old/analyze.c:68:5: note: Storing uninitialized value
  M=malloc(sizeof(unsig)*n); assert(M);
    ^
/home/pi/old/analyze.c:72:12: note: Assuming 'x' is >= 'n'
  for(x=0; x<n; ++x)
           ^
/home/pi/old/analyze.c:72:3: note: Loop condition is false. Execution continues on line 75
  for(x=0; x<n; ++x)
  ^
/home/pi/old/analyze.c:75:3: note: Loop condition is false. Execution continues on line 88
  for(x=0; x<n; ++x)
  ^
/home/pi/old/analyze.c:88:3: note: Loop condition is false. Execution continues on line 90
  for(x=1; x<l; ++x)
  ^
/home/pi/old/analyze.c:91:3: note: Loop condition is false. Execution continues on line 95
  for(x=0; x<n; ++x)
  ^
/home/pi/old/analyze.c:101:3: note: Loop condition is false. Execution continues on line 111
  for(x=0; x<n; ++x)
  ^
/home/pi/old/analyze.c:115:32: note: The right operand of '+' is a garbage value
  printf("lm1 "fmt"\n", L[A[1]]+M[1]);
                               ^
/home/pi/old/analyze.c:116:32: warning: The right operand of '+' is a garbage value [clang-analyzer-core.UndefinedBinaryOperatorResult]
  printf("lm2 "fmt"\n", L[A[2]]+M[2]);
                               ^
/home/pi/old/analyze.c:68:5: note: Storing uninitialized value
  M=malloc(sizeof(unsig)*n); assert(M);
    ^
/home/pi/old/analyze.c:72:12: note: Assuming 'x' is < 'n'
  for(x=0; x<n; ++x)
           ^
/home/pi/old/analyze.c:72:3: note: Loop condition is true.  Entering loop body
  for(x=0; x<n; ++x)
  ^
/home/pi/old/analyze.c:72:12: note: Assuming 'x' is < 'n'
  for(x=0; x<n; ++x)
           ^
/home/pi/old/analyze.c:72:3: note: Loop condition is true.  Entering loop body
  for(x=0; x<n; ++x)
  ^
/home/pi/old/analyze.c:72:12: note: Assuming 'x' is >= 'n'
  for(x=0; x<n; ++x)
           ^
/home/pi/old/analyze.c:72:3: note: Loop condition is false. Execution continues on line 75
  for(x=0; x<n; ++x)
  ^
/home/pi/old/analyze.c:75:3: note: Loop condition is true.  Entering loop body
  for(x=0; x<n; ++x)
  ^
/home/pi/old/analyze.c:76:9: note: Assuming the condition is false
    if (A[x]==0)
        ^
/home/pi/old/analyze.c:76:5: note: Taking false branch
    if (A[x]==0)
    ^
/home/pi/old/analyze.c:75:3: note: Loop condition is true.  Entering loop body
  for(x=0; x<n; ++x)
  ^
/home/pi/old/analyze.c:76:9: note: Assuming the condition is false
    if (A[x]==0)
        ^
/home/pi/old/analyze.c:76:5: note: Taking false branch
    if (A[x]==0)
    ^
/home/pi/old/analyze.c:75:3: note: Loop condition is false. Execution continues on line 88
  for(x=0; x<n; ++x)
  ^
/home/pi/old/analyze.c:88:3: note: Loop condition is false. Execution continues on line 90
  for(x=1; x<l; ++x)
  ^
/home/pi/old/analyze.c:91:3: note: Loop condition is true.  Entering loop body
  for(x=0; x<n; ++x)
  ^
/home/pi/old/analyze.c:91:3: note: Loop condition is true.  Entering loop body
/home/pi/old/analyze.c:91:3: note: Loop condition is false. Execution continues on line 95
/home/pi/old/analyze.c:101:3: note: Loop condition is true.  Entering loop body
  for(x=0; x<n; ++x)
  ^
/home/pi/old/analyze.c:104:5: note: Taking true branch
    if (M[x]>mm)  mm=M[x];
    ^
/home/pi/old/analyze.c:106:5: note: Taking false branch
    if (L[A[x]]>ml)  ml=L[A[x]];
    ^
/home/pi/old/analyze.c:108:5: note: Taking false branch
    if (L[A[x]]+M[x]>mlm)  mlm=L[A[x]]+M[x];
    ^
/home/pi/old/analyze.c:101:3: note: Loop condition is true.  Entering loop body
  for(x=0; x<n; ++x)
  ^
/home/pi/old/analyze.c:104:5: note: Taking false branch
    if (M[x]>mm)  mm=M[x];
    ^
/home/pi/old/analyze.c:106:5: note: Taking false branch
    if (L[A[x]]>ml)  ml=L[A[x]];
    ^
/home/pi/old/analyze.c:108:5: note: Taking false branch
    if (L[A[x]]+M[x]>mlm)  mlm=L[A[x]]+M[x];
    ^
/home/pi/old/analyze.c:101:3: note: Loop condition is false. Execution continues on line 111
  for(x=0; x<n; ++x)
  ^
/home/pi/old/analyze.c:116:32: note: The right operand of '+' is a garbage value
  printf("lm2 "fmt"\n", L[A[2]]+M[2]);
                               ^
Suppressed 58 warnings (58 in non-user code).
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
pi@raspberrypi400:~/old $ 

P.S:
Fixed 31 warnings in factorize.c Gist I use really often the last weeks (revision 10):
https://gist.github.com/Hermann-SW/bfa0 ... ab28057bf6

New was this clang-tidy message:

Code: Select all

warning: different indentation for 'if' and corresponding 'else' [readability-misleading-indentation]
I liked

Code: Select all

        if (...) ...
   else if (...) ...
keeping the IFs above each other, will now use

Code: Select all

   if      (...) ...
   else if (...) ...
to keep if conditions above each other -- and clang-tidy happy.
https://github.com/Hermann-SW/memrun
https://stamm-wilbrandt.de/2wheel_balancing_robot
https://stamm-wilbrandt.de/en#raspcatbot
https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter
https://stamm-wilbrandt.de/en/Raspberry_camera.html

User avatar
jahboater
Posts: 7370
Joined: Wed Feb 04, 2015 6:38 pm
Location: Wonderful West Dorset

Re: [SOLVED] What is wrong with Raspberry struct timespec and splint?

Thu Aug 12, 2021 4:11 pm

Very interesting, thanks!

I do

#define elif else if

to allow more normal "else if" sequences like other languages.
For example:

Code: Select all

  if( event == I_PROM )
    ++lossy_implicit;
  elif( event == W_PROM )
    ++promotions;
  elif( event == W_US_PROM )
    ++signed_unsigned;
Also, for interest :

Code: Select all

/*
 *  C extensions.
 */
#define repeat for(;;)
#define elif else if
#define aligned _Alignas(16)
#define noreturn _Noreturn void
#define csc const * const
enum { no, yes };  // bool
Though I guess "#define loop for(;;)" might be more popular, but C's predecessor (B) used repeat.

User avatar
HermannSW
Posts: 4603
Joined: Fri Jul 22, 2016 9:09 pm
Location: Eberbach, Germany
Contact: Website Twitter YouTube

Re: [SOLVED] What is wrong with Raspberry struct timespec and splint?

Thu Aug 12, 2021 5:27 pm

Nice defines.

My older son pointed to "cppchecker" as well -- took a while to see that it is "cppcheck" only:

Code: Select all

pi@raspberrypi400:~/old $ sudo apt-cache search cppcheck | grep CLI
cppcheck - tool for static C/C++ code analysis (CLI)
pi@raspberrypi400:~/old $ 

This tool is pretty bad, where clang-tidy produce 36/31 warnings, cppcheck shows 0:

Code: Select all

pi@raspberrypi400:~/old $ cppcheck analyze.c 
Checking analyze.c ...
pi@raspberrypi400:~/old $ cppcheck factorize.c 
Checking factorize.c ...
pi@raspberrypi400:~/old $

So I will go with clang-tidy from now on, although my compiler will be gcc.

[I use gcc since 1990, the year I started as computer science researcher at University of Bonn/Germany. In early 90s g++ was just a predecessor for gcc ;-) In that year I started using "vi" (nice for use from home over 2400baud modem line into my Sun MicroSystems workstation at University, "holmium.informatik.uni-bonn.de") -- I use "vi" today still most times, although it became "vim" (vi improved)]

Code: Select all

pi@raspberrypi400:~ $ which vi
/usr/bin/vi
pi@raspberrypi400:~ $ ls -l /usr/bin/vi
lrwxrwxrwx 1 root root 20 Jan 11  2021 /usr/bin/vi -> /etc/alternatives/vi
pi@raspberrypi400:~ $ ls -l /etc/alternatives/vi
lrwxrwxrwx 1 root root 17 Jan 11  2021 /etc/alternatives/vi -> /usr/bin/vim.tiny
pi@raspberrypi400:~ $ 

P.S:
vim on my Intel Linux has 599 syntax files(!) -- one of the reasons I like "vi":

Code: Select all

$ ls -l /usr/share/vim/vim80/syntax | wc --lines
599
$ ls -l /usr/share/vim/vim80/syntax | grep cpp
-rw-r--r--. 1 root root   2869 Jun  3  2020 cpp.vim
-rw-r--r--. 1 root root    600 Jun  3  2020 objcpp.vim
$ 

P.P.S:
Just fixed the missing Raspberry syntax files by "sudo apt install vim".
Now Raspberry has even more than Intel Linux ;-)
And "vi" got changed to use "vim" automatically:

Code: Select all

pi@raspberrypi400:~ $ ls -l /usr/share/vim/vim81/syntax/ | wc --lines
602
pi@raspberrypi400:~ $ which vi
/usr/bin/vi
pi@raspberrypi400:~ $ ls -l `which vi`
lrwxrwxrwx 1 root root 20 Jan 11  2021 /usr/bin/vi -> /etc/alternatives/vi
pi@raspberrypi400:~ $ ls -l /etc/alternatives/vi
lrwxrwxrwx 1 root root 18 Aug 12 19:54 /etc/alternatives/vi -> /usr/bin/vim.basic
pi@raspberrypi400:~ $ 
https://github.com/Hermann-SW/memrun
https://stamm-wilbrandt.de/2wheel_balancing_robot
https://stamm-wilbrandt.de/en#raspcatbot
https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter
https://stamm-wilbrandt.de/en/Raspberry_camera.html

Return to “C/C++”