HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppModerate

Avoiding the 'possible loss of data' compiler warning

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
lossthedatapossiblecompilerwarningavoiding

Problem

I'm writing a file I/O DLL in C++ which is going to be used from VB6. The interface is already fixed, and uses INT64/Currency as the general integer data type.

Now I have this function:

extern "C" LPWIN32_FIND_DATAW ZFILEIO_API GetFileInfoByIndex(INT64 index) {
    return total_size >= 0 
        && index size() 
        && index >= 0 
              ? &file_vec->at(index) 
              : NULL;
}


where file_vec is of type std::vector. Its at member function takes a size_t argument, which is in my case an unsigned 32-bit integer. Therefore, MSVC++2010 warns me of possible data loss. I think nothing can happen in my code, but please correct me if I'm wrong. Also, do you know a method to avoid the warning (without shutting it off for other places in my code)?

And then there's another question; I would like to return the WIN32_FIND_DATAW struct by value, not as a pointer, but that's not possible because then I can't return NULL for illegal requests. Can I return such a pointer to my internal data to a VB6 application?

Solution

Your types are not the same, and you're relying on implicit conversion. The compiler is warning you because not all implicit conversions in this case will be valid. If you know that the conversion is valid in your case, then you should do the conversion explicitly. It's sensible to check the condition you're relying on:

extern "C" LPWIN32_FIND_DATAW ZFILEIO_API GetFileInfoByIndex(INT64 index) {
    assert(index = 0 
        && index size() 
        && index >= 0 ? &file_vec->at(static_cast(index)) : NULL;
}


The check can be either an assert or throw an exception, depending on how confident you are that this condition cannot (even theoretically) be hit in your code. You may also want to make sure that the range of index is checked at a higher level in the code where it can throw a more meaningful exception, e.g. in the constructor of the corresponding type. Even if you do this, keeping an additional check in the code just prior to the cast is useful, because it verifies to a future maintainer that the cast is valid.

If the compiler still complains when you have the explicit cast in place, then I think your only option is to temporarily silence the warning. I still prefer the cast solution even in this case, since it's obvious to the reader that something potentially dangerous is being done.

Note that SIZE_MAX is not defined in the C++ standard AFAICT. It's likely to be available on your platform, but if not there's almost certainly another way of getting the same information, namely the maximum value of size_t.

Code Snippets

extern "C" LPWIN32_FIND_DATAW ZFILEIO_API GetFileInfoByIndex(INT64 index) {
    assert(index <= SIZE_MAX);

    return total_size >= 0 
        && index <= file_vec->size() 
        && index >= 0 ? &file_vec->at(static_cast<size_t>(index)) : NULL;
}

Context

StackExchange Code Review Q#2610, answer score: 11

Revisions (0)

No revisions yet.