Skip to content

Comments

Fix compiler warnings, part 11#1405

Closed
nilason wants to merge 5 commits intoOSGeo:masterfrom
nilason:fix-compiler-warnings-11
Closed

Fix compiler warnings, part 11#1405
nilason wants to merge 5 commits intoOSGeo:masterfrom
nilason:fix-compiler-warnings-11

Conversation

@nilason
Copy link
Contributor

@nilason nilason commented Feb 26, 2021

Fixes compiler warnings:

  • -Wformat
  • -Wpointer-to-int-cast
  • -Wimplicit-int
  • -Wformat-zero-length

Eleventh part addressing #1247.

Modules / code parts directly affected:

  • lib/gis
  • r.sun
  • r.in.mat
  • r.out.mat
  • r.info

@nilason nilason mentioned this pull request Feb 27, 2021
27 tasks
@nilason nilason force-pushed the fix-compiler-warnings-11 branch from c409575 to 225d9d5 Compare March 6, 2021 20:41
lib/gis/spawn.c Outdated
}
else if (arg == SF_REDIRECT_FILE) {
sp->redirects[sp->num_redirects].dst_fd = NEXT_ARG(va, int);
sp->redirects[sp->num_redirects].dst_fd = (int)NEXT_ARG(va, intptr_t);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of intptr_t might need some clarification.
Where pointer size differs from size of integer, the following warning will be issued:

spawn.c: In function ‘parse_argvec’:
spawn.c:734:30: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
  734 | #define NEXT_ARG(var, type) ((type) *(var)++)
      |                              ^
spawn.c:747:48: note: in expansion of macro ‘NEXT_ARG’
  747 |      sp->redirects[sp->num_redirects].dst_fd = NEXT_ARG(va, int);
      |                                                ^~~~~~~~

Test of concept:

#include <stdio.h>

#define SF_SIGNAL            ((const char *) 4)
#define NEXT_ARG(var, type)  ((type) *(var)++)

int main(int argc, const char * argv[])
{
    const char *new_argv[2];
    const char **va = new_argv;
    int int1, int2;

    new_argv[0] = SF_SIGNAL;
    new_argv[1] = SF_SIGNAL;

    // old implementation
    int1 =  NEXT_ARG(va, int);

    // new implementation
    int2 =  (int)NEXT_ARG(va, intptr_t);

    if (int1 == int2)
        puts("equal");
    else
        puts("not equal");

    return 0;
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you aware of any system/compiler where pointer size is smaller than integer size? Only under this condition becomes the warning meaningful.

intptr_t requires C99.

According to the logic of spawn.c, it should really be NEXT_ARG(va, int); in L747, because va contains pointers to different types, and here it should be int, thus (int) *(va)++ equals (intptr_t) *(va)++ only if int and intptr_t have the same size.

IMHO, this is the wrong way to suppress the compiler warning.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you aware of any system/compiler where pointer size is smaller than integer size? Only under this condition becomes the warning meaningful.

This is the kind of warning that only adds noise. This code causing the warnings will most likely never cause failure (partly as you say because pointers are not likely to be smaller than ints ). In particular as the int values passed by va are mostly (perhaps exclusively) in the range of 0-9. This is probably the reason I cannot provoke Clang to come up with this warning (despite difference in size between pointer and int). The warnings come from the CIs GCC builds.
However, if there is a valid way to reduce noise, why not.

intptr_t requires C99.

I know.

According to the logic of spawn.c, it should really be NEXT_ARG(va, int); in L747, because va contains pointers to different types, and here it should be int, thus (int) *(va)++ equals (intptr_t) *(va)++ only if int and intptr_t have the same size.

If I'm not totally mistaken, the va pointers "to" ints, are in fact pointers with the value of the int to be passed, not pointer to int. The (int) *(va)++ in fact casts the value of a pointer (of size intptr_t) to an int (hence the warning).

IMHO, this is the wrong way to suppress the compiler warning.

What would you say of adding a macro for reading int:

#define NEXT_ARG_INT(var) (int)((intptr_t) *(var)++)
...
// to be used like:
sp->redirects[sp->num_redirects].dst_fd = NEXT_ARG_INT(va);

this way the code will be cleaner and made obvious of what is expected?

The alternative solutions I can think of are all inelegant and unnecessarily complicated -- or we accept the warnings.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to the logic of spawn.c, it should really be NEXT_ARG(va, int); in L747, because va contains pointers to different types, and here it should be int, thus (int) *(va)++ equals (intptr_t) *(va)++ only if int and intptr_t have the same size.

If I'm not totally mistaken, the va pointers "to" ints, are in fact pointers with the value of the int to be passed, not pointer to int. The (int) *(va)++ in fact casts the value of a pointer (of size intptr_t) to an int (hence the warning).

You're right, va is a pointer to pointers of char, the value of interest is not where **va points to, but the address of *va, and the address of the pointer is cast to int (in this case).

IMHO, this is the wrong way to suppress the compiler warning.

What would you say of adding a macro for reading int:

#define NEXT_ARG_INT(var) (int)((intptr_t) *(var)++)
...
// to be used like:
sp->redirects[sp->num_redirects].dst_fd = NEXT_ARG_INT(va);

this way the code will be cleaner and made obvious of what is expected?

But with this on 64bit systems, you are still casting a 64bit int to a 32bit int. We want to cast a pointer to a char (the address of that pointer) to an int, right? Without the compiler complaining about it. This will be an arms race with compilers becoming more clever.

So far,
#define NEXT_ARG_INT(var) (int)((intptr_t) *(var)++)
seems to work without complaints, even though it casts a 64bit int to a 32bit int. Seems to be a feature (?) in gcc that int conversion to a different size is allowed, potentially causing integer overflow.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is my understanding that
#define NEXT_ARG_INT(var) (int)((intptr_t) *(var)++) reflects what the compiler actually does. The difference is that in this way the casts are explicit and therefore makes gcc happy.

Copy link
Contributor

@metzm metzm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is what we want the compiler to do: cast a pointer to an integer of smaller size. The compiler does not like this and issues a warning. Thus we cast the pointer to an integer of the same size, then cast that integer to a smaller size which the compiler thinks is ok, thus we are tricking the compiler. In this case we are sure that this casting is ok. OK for me to merge.

Thanks a lot for the discussion!

@nilason
Copy link
Contributor Author

nilason commented Mar 10, 2021

This is what we want the compiler to do: cast a pointer to an integer of smaller size. The compiler does not like this and issues a warning. Thus we cast the pointer to an integer of the same size, then cast that integer to a smaller size which the compiler thinks is ok, thus we are tricking the compiler. In this case we are sure that this casting is ok. OK for me to merge.

Thanks a lot for the discussion!

Just pushed an update using new NEXT_ARG_INT(var) macro. If you don't mind that change and the CIs are good with it I'll merge tomorrow.

I wouldn't say we're "tricking" the compiler, we just say this particular downcast (if there is any) is ok, is just what we want.
I thank you! I very much appreciate your patience with me and my warnings.

@nilason nilason marked this pull request as ready for review March 10, 2021 22:27
nilason added a commit that referenced this pull request Mar 11, 2021
Addresses -Wformat compiler warning.
nilason added a commit that referenced this pull request Mar 11, 2021
Addresses -Wformat-zero-length compiler warnings.
nilason added a commit that referenced this pull request Mar 11, 2021
For now only comments out relevant parts.
Addresses -Wimplicit-int compiler warnings.
nilason added a commit that referenced this pull request Mar 11, 2021
Addresses -Wpointer-to-int-cast compiler warnings.
@nilason
Copy link
Contributor Author

nilason commented Mar 11, 2021

Cherry picked and pushed manually.
Thanks!

@nilason nilason closed this Mar 11, 2021
@nilason nilason deleted the fix-compiler-warnings-11 branch March 11, 2021 19:20
lindakarlovska pushed a commit to lindakarlovska/grass that referenced this pull request Mar 15, 2021
lindakarlovska pushed a commit to lindakarlovska/grass that referenced this pull request Mar 15, 2021
Addresses -Wformat-zero-length compiler warnings.
lindakarlovska pushed a commit to lindakarlovska/grass that referenced this pull request Mar 15, 2021
For now only comments out relevant parts.
Addresses -Wimplicit-int compiler warnings.
lindakarlovska pushed a commit to lindakarlovska/grass that referenced this pull request Mar 15, 2021
Addresses -Wpointer-to-int-cast compiler warnings.
marisn pushed a commit to marisn/grass that referenced this pull request Mar 22, 2021
marisn pushed a commit to marisn/grass that referenced this pull request Mar 22, 2021
Addresses -Wformat-zero-length compiler warnings.
marisn pushed a commit to marisn/grass that referenced this pull request Mar 22, 2021
For now only comments out relevant parts.
Addresses -Wimplicit-int compiler warnings.
marisn pushed a commit to marisn/grass that referenced this pull request Mar 22, 2021
Addresses -Wpointer-to-int-cast compiler warnings.
@neteler neteler added this to the 8.0.0 milestone Dec 9, 2021
ninsbl pushed a commit to ninsbl/grass that referenced this pull request Oct 26, 2022
ninsbl pushed a commit to ninsbl/grass that referenced this pull request Oct 26, 2022
Addresses -Wformat-zero-length compiler warnings.
ninsbl pushed a commit to ninsbl/grass that referenced this pull request Oct 26, 2022
For now only comments out relevant parts.
Addresses -Wimplicit-int compiler warnings.
ninsbl pushed a commit to ninsbl/grass that referenced this pull request Oct 26, 2022
Addresses -Wpointer-to-int-cast compiler warnings.
ninsbl pushed a commit to ninsbl/grass that referenced this pull request Feb 17, 2023
ninsbl pushed a commit to ninsbl/grass that referenced this pull request Feb 17, 2023
Addresses -Wformat-zero-length compiler warnings.
ninsbl pushed a commit to ninsbl/grass that referenced this pull request Feb 17, 2023
For now only comments out relevant parts.
Addresses -Wimplicit-int compiler warnings.
ninsbl pushed a commit to ninsbl/grass that referenced this pull request Feb 17, 2023
Addresses -Wpointer-to-int-cast compiler warnings.
nilason added a commit to nilason/grass that referenced this pull request Jul 24, 2023
This is a partial, manual backport of OSGeo#1405.
The warning is treated as an error by Clang 16+ and the compilation fails.
nilason added a commit to nilason/grass that referenced this pull request Jul 31, 2023
For now only comments out relevant parts.
Addresses -Wimplicit-int compiler warnings.
The warning is treated as an error by Clang 16+ and the compilation fails.

This is a partial, manual backport of OSGeo#1405,
commit 594c947.
nilason added a commit that referenced this pull request Aug 6, 2023
For now only comments out relevant parts.
Addresses -Wimplicit-int compiler warnings.
The warning is treated as an error by Clang 16+ and the compilation fails.

This is a partial, manual backport of #1405,
commit 594c947.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants