Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Compiler Warnings: Ignore at Your Own Risk

0.00/5 (No votes)
28 Jun 2015 1  
While you can often get away with ignoring compiler warnings, failing to at least scan them can bite hard!

Introduction

Especially in the early stages of development, it is tempting to ignore compiler warnings without much thought, or, at the very least, set them aside to address in a subsequent build. However, this is not always true, since there are a handful of warnings that could justify promotion to fatal errors that stop a build short of the link step.

Background

Today, I added a pair of new routines to the fixed string buffers library that I presented in "Using Static Buffers to Improve Error Reporting Success;" Following my standard practice, I next added a new routine to the accompanying test program, compiled and linked it, and was about to test it.

Then, I noticed two little warnings, both referring to the same line in the test program source,

  1. warning C4047: 'function' : 'LPCTSTR' differs in levels of indirection from 'FB_RES_STRING_ID'
  2. warning C4024: 'FB_FormatMessageW' : different types for formal and actual parameter 1

C4047 is a familiar warning that can often be safely ignored. C4024 is a different story. Though I understand why it is classified as such, this is a warning that the wise coder investigates before proceeding to the next step.

Following is the statement that elicited both warnings.

_tprintf ( FBT_LoadUtilityString ( IDS_STRING24 ) ,              // Format control string
           FB_FormatMessageW ( puintHintStringID ,               // unsigned int
                                                                 // puintHintStringID
                               rintRC ,                          // const DWORD pdwLastError
                               aenmCodeFormat [ uintCase ] ) ) ; // STATUS_CODE_FORMAT2
                                                                 // penmCodeFormat

A quick check of the FB_FormatMessage call against its signature, alongside that of the new function that this routine is supposed to test reveals the cause of both warnings, and why it is imperative that they be resolved before I test it.

    LPTSTR WINAPI FB_FormatMessageW
    (
        LPCTSTR                 plpHint ,   	// String to display at beginning of message, 
        				        // offering hints to direct the investigator
                                      	        // to the source of the error
        const DWORD             pdwLastError ,  // Result returned by GetLastError, 
        				        // from which to format a SYSTEM error message
        CSTATUS_CODE_FORMAT2    penmCodeFormat  // STATUS_CODE_FORMAT2 enumeration member 
                    		                // to specify whether the status code should 
                                                // be displayed in decimal or hexadecimal
    ) ;

    LPTSTR WINAPI FB_FormatMessage2W
    (
        unsigned int            puintHintStringID , // Resource ID of string to display
        			                    // at beginning of message, offering hints 
        			                    // to direct the inveistgator to the source
                                                    // of the error
        const DWORD             pdwLastError ,      // Result returned by GetLastError, 
        				            // from which to format a SYSTEM error message
        CSTATUS_CODE_FORMAT2    penmCodeFormat 	    // STATUS_CODE_FORMAT2 enumeration member 
        				            // to specify whether the status code should 
                                                    // be displayed in decimal or hexadecimal
    ) ;

The first #if block defines FIXEDSTRINGBUFFERS_API correctly for a routine that is exported by a DLL, and was generated by the application wizard when I created the project. The last block above is the standard entry point symbol mapping, which explains why the signatures are of FB_FormatMessageW and FB_FormatMessage2W, while the call is to FB_FormatMessage. Since it deals with the legacy ANSI encoding, and is irrelevant, I omitted the #else block.

The following table lists the names and types of parameter 1 of the old function, FB_FormatMessage, and the new one, FB_FormatMessage2.

Parameter Types for Parameter 1: FB_FormatMessage vs FB_FormatMessage2

Function Name Type Comment
FB_FormatMessageW plpHint LPCTSTR String to display at the beginning of message, offering hints to direct the investigator to the source of the error
FB_FormatMessage2W puintHintStringID unsigned int Resource ID of string to display at the beginning of message, offering hints to direct the investigator to the source of the error

Corrective Action

The types displayed in the third column of the table above make it evident that the values in the code are correct, but the function name is wrong. Substituting FB_FormatMessage2 for FB_FormatMessage corrects the design error and resolves both warnings.

_tprintf ( FBT_LoadUtilityString ( IDS_STRING24 ) ,               // Format control string
           FB_FormatMessage2W ( puintHintStringID ,               // unsigned int
                                                                  // puintHintStringID
                                rintRC ,                          // const DWORD pdwLastError
                                aenmCodeFormat [ uintCase ] ) ) ; // STATUS_CODE_FORMAT2
                                                                  // penmCodeFormat

Lesson Reinforced

Always investigate warning C4024, without exception. There are, of course, times when it is safe to ignore it, because the compiler uses it to call attention to the most trivial differences between the types shown in the signature and the types specified in the argument list. Nevertheless, it bears a quick check of the actual arguments against the declaration.

Thankfully, I caught this error before I executed the first test, but I am not always that lucky. Had I executed the code as first written, the machine would have interpreted the resource ID as a very low machine address, and killed the process with the dreaded 0x00000005 (access violation) status code. Who knows how much time I would have wasted on that error?

History

  • Sunday, 28th June 2015: First publication
  • Monday 29th June 2015: Example simplified

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here