You are not logged in.

#1 2012-12-24 11:10:58

neok
Member
From: Cyprus
Registered: 2003-12-14
Posts: 190
Website

Strict type checking in C source?

Hi and Merry Xmass to all,

I have a rather large code base in C for an application that is heavy on math, mostly in complex double numbers, and I am trying to produce a version with long double precision for some very difficult jobs. There is a very large number of math functions, both in real and complex type, and I want to make sure that automatic type casting is not reducing long double values to double, spoiling precision.

Is there a way to either statically check the source code for type mismatches, or make gcc or clang not to accept non-explicit type casting? I tried splint but it fails because some declarations in complex.h confuse it.

My thanks in advance!


Regards

Neoklis ... Ham Radio Call: 5B4AZ

Offline

#2 2012-12-24 12:33:57

Cloudef
Member
Registered: 2010-10-12
Posts: 636

Re: Strict type checking in C source?

According to GCC's documentation -Wextra should give warnings for loss of precision.
But for some reason it doesn't when I tested.

-Wconversion however seems to work. Just make sure you don't typecast in code since compiler believes that's the behaviour you want obiviously.
There is also treat warnings as error compile option that you can combine with this.

int main(int argc, char **argv)
{
   long double d = 1.5;
   double d2 = d;
   double i_want_to_do_this = (double)d;
   int d3 = d2;
   return 0;
}
─┬╼ .loli//LOLI :: /home/loli
 └╼ ] gcc -Wconversion main.c                                                                                                    
main.c: In function ‘main’:
main.c:4:4: warning: conversion to ‘double’ from ‘long double’ may alter its value [-Wconversion]
main.c:6:4: warning: conversion to ‘int’ from ‘double’ may alter its value [-Wconversion]

That said, type-safe code is way to go and it's good idea to do this.

Last edited by Cloudef (2012-12-24 12:38:46)

Offline

#3 2012-12-24 13:55:26

Trent
Member
From: Baltimore, MD (US)
Registered: 2009-04-16
Posts: 987

Re: Strict type checking in C source?

Terminology: A cast is a explicit conversion. "Automatic cast" is a contradiction in terms. (And "type casting" is something that happens to actors.)

-Wconversion only warns about implicit conversions; casting is a syntax that makes conversions explicit, so the compiler will assume you know what you're doing when you cast something. This isn't a problem if you don't use unnecessary casts.

Offline

#4 2012-12-24 18:18:58

neok
Member
From: Cyprus
Registered: 2003-12-14
Posts: 190
Website

Re: Strict type checking in C source?

Cloudef wrote:

That said, type-safe code is way to go and it's good idea to do this.

Thanks for the tips and the straightening of the terminology (I am completely self-taught).

Quite right about type-safe code and using -Wconversion - I got dozens of warnings about type conversions of which one was a real bug (a variable declared double instead of int, but as it was initialized by an int and passed as an argument to a function in a position were an int was expected, it didn't cause any problems. However its still a bug.

Unfortunately, -Wconversion doesn't produce warnings when certain functions are given a wrong type of argument. For example, with creall() and cabsl() complex double arguments seem to be accepted. With other functions of long double type like sqrtl(), double arguments cause gcc to give conversion warnings.


Regards

Neoklis ... Ham Radio Call: 5B4AZ

Offline

#5 2012-12-24 19:10:30

Trent
Member
From: Baltimore, MD (US)
Registered: 2009-04-16
Posts: 987

Re: Strict type checking in C source?

double complex -> long double complex is a widening conversion. Why would you want to be warned about it?

Edit btw: calling sqrtl() on a double doesn't result in a warning for me regardless of flags.

Last edited by Trent (2012-12-24 19:14:00)

Offline

#6 2012-12-24 19:48:01

Cloudef
Member
Registered: 2010-10-12
Posts: 636

Re: Strict type checking in C source?

Quite right about type-safe code and using -Wconversion - I got dozens of warnings about type conversions of which one was a real bug (a variable declared double instead of int, but as it was initialized by an int and passed as an argument to a function in a position were an int was expected, it didn't cause any problems. However its still a bug.

Yeah, but you should not go overboard though, or your code will look mess of all the typecasting madness smile
There's reason why -Wconversion is off by default.

As for the other issue, widening should not give warning as Trent said.

Offline

#7 2012-12-25 07:38:07

neok
Member
From: Cyprus
Registered: 2003-12-14
Posts: 190
Website

Re: Strict type checking in C source?

neok wrote:

Unfortunately, -Wconversion doesn't produce warnings when certain functions are given a wrong type of argument. For example, with creall() and cabsl() complex double arguments seem to be accepted. With other functions of long double type like sqrtl(), double arguments cause gcc to give conversion warnings.

My apologies, got it the wrong way round, I was expecting warnings when passing long arguments to double functions.
I tried a little dummy code and got the following:

long double x;
complex long double z = 1.0 + I * 1.0;
double a;

278 x = creall( z ); /* Function long double, arg complex long double */
279 a = creal( z );  /* Function double, arg complex long double */
280 x = fabsl( x );  /* All long double */
281 a = fabs( x );   /* Function double, arg long double */

I was expecting a warning for line 279, were the function is type double and requires a complex double argument, but the argument is type complex long double. Got such a warning for line 281, were the function is not of complex type.

|| calculations.c: In function ‘cabc’:
calculations.c|281 col 1| warning: conversion to ‘double’ from ‘long double’ may alter its value [-Wconversion]

Regards

Neoklis ... Ham Radio Call: 5B4AZ

Offline

#8 2012-12-25 14:18:20

Trent
Member
From: Baltimore, MD (US)
Registered: 2009-04-16
Posts: 987

Re: Strict type checking in C source?

Huh, you're right. Merry Christmas, you may have discovered a bug in gcc.

Offline

#9 2012-12-25 15:13:45

neok
Member
From: Cyprus
Registered: 2003-12-14
Posts: 190
Website

Re: Strict type checking in C source?

Trent wrote:

Huh, you're right. Merry Christmas, you may have discovered a bug in gcc.

Hmmm, unlikely that I would discover a bug in gcc, I will make more tests later, after I digest my Xmass food and drink....

Merry Xmass all!


Regards

Neoklis ... Ham Radio Call: 5B4AZ

Offline

#10 2012-12-25 15:29:52

Cloudef
Member
Registered: 2010-10-12
Posts: 636

Re: Strict type checking in C source?

@neok
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48956
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50992

This is your code compiled with clang:

└╼ ] clang main.c -Wconversion                                                                                                    ─
main.c:12:15: warning: implicit conversion loses floating-point precision: '_Complex long double' to '_Complex double' [-Wconversion]
   a = creal( z );  /* Function double, arg complex long double */
       ~~~~~  ^
main.c:14:14: warning: implicit conversion loses floating-point precision: 'long double' to 'double' [-Wconversion]
   a = fabs( x );   /* Function double, arg long double */
       ~~~~  ^

Last edited by Cloudef (2012-12-25 15:31:33)

Offline

#11 2012-12-25 19:15:23

neok
Member
From: Cyprus
Registered: 2003-12-14
Posts: 190
Website

Re: Strict type checking in C source?

Hmmm, so I should have made a search for a possible bug report, but I was more inclined to think that I was doing something wrong. I should have thought of trying clang though, it is available in Arch.

Thanks everyone for the hints and help, even on Xmass day!


Regards

Neoklis ... Ham Radio Call: 5B4AZ

Offline

#12 2012-12-25 19:43:11

neok
Member
From: Cyprus
Registered: 2003-12-14
Posts: 190
Website

Re: Strict type checking in C source?

neok wrote:

Hmmm, so I should have made a search for a possible bug report, but I was more inclined to think that I was doing something wrong. I should have thought of trying clang though, it is available in Arch.

Thanks everyone for the hints and help, even on Xmass day!

Well, I did try it, and got some more, new warnings:

  tsmag = 100.0l * ck1 * conjl(ck1);

I got this warning:

somnec.c|131 col 19| warning: implicit conversion discards imaginary component: '_Complex long double' to 'long double' [-Wconversion]

Well, the imaginary component would be zero, but that will also depend on operator precedence. I put ck1 * conjl(ck1) in brackets but still got the same warning. So I used this solution:

  tsmag = 100.0l * creall( ck1 * conjl(ck1) );

No warnings this time, but I will have to test the numerical result later, just in case it differs.

Well done clang and FreeBSD, they have switched to clang in 9.0 RELEASE, I believe. But it might have other quirks possibly...


Regards

Neoklis ... Ham Radio Call: 5B4AZ

Offline

Board footer

Powered by FluxBB