NO

Author Topic: Inappropriate warnings  (Read 7717 times)

mtx500

  • Guest
Inappropriate warnings
« on: January 11, 2005, 05:13:02 PM »
While compiling loads of C sources, I noticed some inappropriate warnings which I isolated into small examples for easy reproduction.

All examples are compiled with "pocc.exe /O2 /W2 source.c".
I marked the warned line with // <--.


Example 1:
Code: [Select]

#include <string.h>

char * buf;

void Function(char * result)
{
    memcpy(result, buf, 4);  // <--
}

// POCCWarn1.c(5): warning #2118: Parameter 'result' is not referenced.

Intrinsic functions don't reference parameters.


Example 2:
Code: [Select]

extern void WriteByte(void * pDst, unsigned char cVal);

void Function(int iKey, unsigned int uiCount, void * pSrc, void * pDst)
{
    switch(iKey) {
    case 0:
        while (1) {
            WriteByte(pDst, *(unsigned char *) pSrc);
            if (--uiCount == 0) break;
            pSrc = ((unsigned char *) pSrc) + 1;
            pDst = ((unsigned char *) pDst) + 1;
        }
        break;  // <--
    default:
        WriteByte(pDst, 4u);
        break;
    }
}

// POCCWarn2.c(13): warning #2209: Unreachable code removed.

Ok, there's that while(1) endless loop, but there's a break inside the loop so the outer break _is_ reached!


Example 3:
Code: [Select]

extern unsigned short Func2(void);

void Func1(void)
{
    Func2();  // <--
}

// POCCWarn3.c(5): warning #2046: Expression with no effect removed.

Making Func2 to a function returning void makes the warning go away. I hope it's only the result of Func2 that is removed, not the call to Func2 itself!


Example 4:
Code: [Select]

void Func(unsigned char ucType);

void Func(unsigned char ucType)
{
    if (ucType == 0)
    {
        _asm {int 3}  //<--
    };
    if (ucType & 0x2000)
    {
        //_asm {int 3}
    };
}

// POCCWarn4.c(7): warning #3039: [asm] 'byte' value exceeds bounds.

This one caused me some headaches. The "[asm]" did lead me in a completely wrong direction. Actually, the warning is caused by line #9: an unsigned char cannot have bit mask 0x2000 set. But in my source code, this warning appeared hundreds of lines of code apart from that location. That was very difficult to find!

Offline Pelle

  • Administrator
  • Member
  • *****
  • Posts: 2266
    • http://www.smorgasbordet.com
Re: Inappropriate warnings
« Reply #1 on: January 11, 2005, 06:18:55 PM »
Quote from: "mtx500"
Example 1:
// POCCWarn1.c(5): warning #2118: Parameter 'result' is not referenced.

Bummer. Will try to fix it to the next beta. (Must remember to test more with warning level 2!).

Quote from: "mtx500"

Example 2:
// POCCWarn2.c(13): warning #2209: Unreachable code removed.

It's not a very relevant warning. I actually added warning 2209 because I wasn't 100% sure about the algorithm. Most compilers will do this type of optimizations without shouting about it. One way or the other, I will try to remove the warning to the next beta.

Quote from: "mtx500"

Example 3:
// POCCWarn3.c(5): warning #2046: Expression with no effect removed.

The call is still there! Not sure what the compiler is complaining about. Will have to investigate. Should also be fixed to the next beta.

Quote from: "mtx500"

Example 4:
// POCCWarn4.c(7): warning #3039: [asm] 'byte' value exceeds bounds.

This one caused me some headaches...

I can understand your problems! I think it's because the expression is promoted to an int in this case, so the compiler think it's OK. In the end, it's the assembler that actually finds the problem - hence the [asm] ...
Will have to investigate this too - hopefully fixed to the next beta.

Pelle
/Pelle

mtx500

  • Guest
Re: Inappropriate warnings
« Reply #2 on: January 25, 2005, 05:14:45 PM »
Quote from: "Pelle"
Will try to fix it to the next beta.


I checked V3.00 Beta 2 and it looks good. Thank's very much!

Just one more example of a warning that I can't explain. I isolated it to a small example. Pelles C complains about all our virtual function tables and all the function pointers inside.

Compile with pocc.exe /O2 /W2 /Ze file.c.
Code: [Select]
extern int __stdcall Method1(
void * Handle);

extern int __stdcall Method2(
void * Handle);

static const long (__stdcall * const (VirtualFunctionTable[]))() =
{
    (const long (__stdcall * const)()) Method1,
    (const long (__stdcall * const)()) Method2
};

// POCCWarn5.c(7): warning #2028: Missing prototype.
// POCCWarn5.c(9): warning #2028: Missing prototype.
// POCCWarn5.c(10): warning #2028: Missing prototype.


Well, there are function prototypes for the two methods - what other prototypes do I need  :?:

Offline Pelle

  • Administrator
  • Member
  • *****
  • Posts: 2266
    • http://www.smorgasbordet.com
Inappropriate warnings
« Reply #3 on: January 25, 2005, 08:36:44 PM »
I assume the methods take no arguments - in C++ you can use () for no arguments, but in C you need to use (void).

The warning can be probably be clearer, but otherwise it looks OK.

Pelle
/Pelle

mtx500

  • Guest
Inappropriate warnings
« Reply #4 on: January 26, 2005, 11:13:41 AM »
Quote from: "Pelle"
in C++ you can use () for no arguments, but in C you need to use (void).


Ah, yes. Now that you mentioned it, it's very clear. But although I stared at the code for quite some time, I didn't see it. Inserting void makes the warning vanish.

It's astonishing that five out of six compilers did not complain about this although we set the warning level as high as possible and set options to check for strict ANSI C compliance wherever possible.

Offline Pelle

  • Administrator
  • Member
  • *****
  • Posts: 2266
    • http://www.smorgasbordet.com
Inappropriate warnings
« Reply #5 on: January 26, 2005, 12:08:26 PM »
Maybe because () is "old style" for any number of arguments - sort of OK. In C99, as I understand it, you must always have a prototype.

Pelle
/Pelle

mtx500

  • Guest
Inappropriate warnings
« Reply #6 on: January 26, 2005, 02:37:14 PM »
Hm, I think I got one more:

I compile with pocc.exe /O2 /W2 POCCWarn6.c:

Code: [Select]
#include <stddef.h>

typedef void (* funcpointer)(void);

funcpointer fpTest;

void Function(void) {
fpTest = NULL;
}

// POCCWarn6.c(8): warning #2006: [ISO] Conversion from 'void *' to 'void __cdecl function(void) *' is compiler dependent.


Have a look at the ISO/IEC standard, chapter "Other operands"-"Pointers" (in my version it is chapter 6.3.2.3).
Paragraph 3 says:
Quote
An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant. If a null pointer constant is assigned to or compared for equality to a pointer, the constant is converted to a pointer of that type.
Such a pointer, called a null pointer, is guaranteed to compare unequal to a pointer to any object or function.


Paragraph 4 says:
Quote
Conversion of a null pointer to another pointer type yields a null pointer of that type. Any two null pointers shall compare equal.


The warning is about mixing function pointers and non-function pointers, but paragraph 3+4 do not make any difference between these. So, as I understand the standard, the compiler should not issue this warning if the value is a null pointer constant (i.e. 0 or (void *0)).

mtx500

  • Guest
Inappropriate warnings
« Reply #7 on: January 26, 2005, 02:45:50 PM »
Another small issue regarding warnings:

The compiler's warning text output ends each line with CR CR LF instead of CR LF. (CR = carriage return = 0x0D, LF = line feed = 0x0A.)
Maybe there is a "\r\n" somewhere instead of only a "\n".

Redirecting the output into a file and viewing this file sometimes shows an empty line after each warning line (depending on the tool one uses to view the file).

Offline Pelle

  • Administrator
  • Member
  • *****
  • Posts: 2266
    • http://www.smorgasbordet.com
Inappropriate warnings
« Reply #8 on: January 26, 2005, 03:20:02 PM »
Right. The messages are coming from a MESSAGETABLE resource, always ending in CR+LF - I think this is messing up the output code. Will try to fix it to the next beta.

Pelle
/Pelle

Offline Pelle

  • Administrator
  • Member
  • *****
  • Posts: 2266
    • http://www.smorgasbordet.com
Inappropriate warnings
« Reply #9 on: January 26, 2005, 04:10:59 PM »
Quote from: "mtx500"
The warning is about mixing function pointers and non-function pointers, but paragraph 3+4 do not make any difference between these. So, as I understand the standard, the compiler should not issue this warning if the value is a null pointer constant (i.e. 0 or (void *0)).

Yes - a NULL pointer seems to be a special case. Will try to fix this too.

Pelle
/Pelle