[Pure C] Clang is better than GCC

Sorry for the provocative title, but I'm too emotional these days.

This code:

#include <stdio.h>
#include <string.h>

struct tmp
{
  int x, y, z;
};

int main()
{
  struct tmp* m_result_original=NULL;
  struct tmp* m_result_my_version=NULL;

  // m_result_original=do_something_version_1();
  // m_result_my_version=do_something_version_2();

  if (memcmp(m_result_original, m_result_my_version, sizeof(struct tmp)!=0))
    {
      printf ("Error - test failed!\n");
    };
};

There is an unnoticed typo. in memcmp(). I wrote here:

  if (memcmp(m_result_original, m_result_my_version, sizeof(struct tmp)!=0))

But must be (note closing brackets at the end):

  if (memcmp(m_result_original, m_result_my_version, sizeof(struct tmp))!=0)

Yes, this is a problem of weak static typing of pure C. Pure C is a great tool for some jobs, but here be dragons, as they say.

The problem is that (sizeof(struct ...)!=0)==1, so size=1 always for memcmp(). Instead of comparing two tmp, my code compared only 1 byte of each structs.

And GCC 9.4 was silent, even with -Wall, and so is G++. And MSVC 2017 is silent as well, with /Owall. But Clang 10 warns even without -Wall:

2.c:17:72: warning: size argument in 'memcmp' call is a comparison [-Wmemsize-comparison]
  if (memcmp(m_result_original, m_result_my_version, sizeof(struct tmp)!=0))
                                                     ~~~~~~~~~~~~~~~~~~^~~
2.c:17:7: note: did you mean to compare the result of 'memcmp' instead?
  if (memcmp(m_result_original, m_result_my_version, sizeof(struct tmp)!=0))
      ^                                                                   ~
                                                                       )
2.c:17:54: note: explicitly cast the argument to size_t to silence this warning
  if (memcmp(m_result_original, m_result_my_version, sizeof(struct tmp)!=0))
                                                     ^
                                                     (size_t)(            )
1 warning generated.

Yes, venerable GCC is a very important and respected tool. And this is my bug, not GCC's flaw.

But that bug in my code ruined one month of my work. I coded without realizing tests don't work at all. OUCH!

I probably should have tried Clang at start. Or try several compilers in parallel, maybe? Or maybe I should stop using pure C...


Comments at lobste.rs, comments at HN, more comments at HN.

(the post first published at 20221126.)


List of my other blog posts.

Yes, I know about these lousy Disqus ads. Please use adblocker. I would consider to subscribe to 'pro' version of Disqus if the signal/noise ratio in comments would be good enough.