I had to re-image my laptop recently, and reinstalled visual studio (Tried 2018 but it annoyed me, so i rolled back to 2015 which seems to work a lot better)
I opened up an old project, and at first it said failed to find build toolset, so i re-targeted it to the one i had just installed. And tried again to compile, and it failed telling me that in the following function:
string getinvnum(vstring range) {
int inv;
string ret;
for (int i = 0; i < range.size(); i++) {
int temp = stoi(range[i]);
if (temp > inv) {
inv = temp;
}
}
return to_string(inv);}
that cpp(266): error C4700: uninitialized local variable 'inv' used. and defiantly refuses to compile.
Line 266 is relating to the if statement there.
This is not a complex function at all, and it most surely is initialized, in fact if i hover my mouse over "inv" intellisense picks up it's deceleration.
I then decided to copy and paste my source code into a new project as this error just made no sense to me, commented out code relating to other included project files, and tried to recompile, and it worked without any complaints.
Is there something wrong with this code, or some issue with the change in toolset?
While everything is working, i'd just like to understand, if possible what happened/what i did which caused this error.
Can anyone explain to me why visual studio is doing this to me?
Edit: Just copied across the whole solution into a new project, and the entire thing now builds without any issues. However the original, while identical code, still tells me this same error.
inv is not initialised. Depending on project compiler settings, the compiler version and whether you are using debug or release the compiler may or may not detect this.
To fix the issue simply initialise inv to have an initial value. The compiler is trying to protect you against difficult to find bugs due to inv having some random value (which may work sometimes as that random value may be 0).
Yes it's an error - a logical error at least - as others have pointed out. You should not ignore compiler warnings, you should fix them. MSVC will always warn you about this (and other things) unless you explicitly turn warnings off so be on the lookout in future and pay due attention. Whether you should tell the compiler to treat warnings as errors is another matter. I don't. Opinions vary.
But I have a more specific reason for posting this answer. In DEBUG builds, The Visual Studio debugger will alert you (with a popup) at runtime if you use an uninitialised variable and show you exactly where you did so. So, always run your code under the debugger and then you will be alerted to mistakes like this, even if you miss the compiler warning.
Related
I am trying to do book-keeping and cleaning my code.
I corrected all warning, but I cannot avoid following warning in xmemory, utility and tuple.
These particular warning points not to my code but to the source of C++.
Even it does that, does it mean that there is something wrong with my code?
Is there a possibility to know where in my code I cause these issues to happen.
If I double click to warnings they point me to these xmemory, utility and tuple files that I never changed.
Following is the screenshots of warnings that I try to resolve:
I'm doing my coding in solidity while coding , I'm getting this error as follow;
at the highlighted line I got the problem.
Kindly let me know what to do.
Is it an error, or just a warning? From the looks of it, you've just created a variable that you do not use. And the program is letting you know through this warning.
Warnings are technically harmless, and they shouldn't prevent your program from running, but the warning does reminds you about this unused line in case you're missing something out. If that's not the case, you can either ignore it or delete that line of code.
It is possible that the program will already give you warnings before you've even finished your bit of code. That behaviour is normal, as they like to be pre-cautious. In that case, you can just ignore it and continue your coding until the variable is used, then the warning will disappear on it's own.
i think you just activated auto compiled
#include <vector>
std::vector<int>::iterator foo();
void bar(void*) {}
int main()
{
void* p;
while (foo() != foo() && (p = 0, true))
{
bar(p);
}
return 0;
}
Results in error:
c:\users\jessepepper\source\repos\testcode\consoleapplication1\consoleapplication1.cpp(15): error C4703: potentially uninitialized local pointer variable 'p' used
It's kind of a bug, but very typical for the kind of code you write.
First, this isn't an error, it's a warning. C4703 is a level 4 warning (meaning that it isn't even enabled by default). So in order to get it reported as an error (and thus interrupt compilation), compiler arguments or pragmas were passed to enable this warning and turn it into an error (/W4 and /Werror are the most likely I think).
Then there's a trade-off in the compiler. How complex should the data flow analysis be to determine whether a variable is actually uninitialized? Should it be interprocedural? The more complex it is, the slower the compiler gets (and because of the halting problem, the issue may be undecidable anyway). The simpler it is, the more false positives you get because the condition that guarantees initialization is too complex for the compiler to understand.
In this case, I suspect that the compiler's analysis works as follows: the assignment to p is behind a conditional (it only happens if foo() != foo()). The usage of p is also behind a conditional (it only happens if that complex and-expression is true). The compiler cannot establish a relationship between these conditions (the analysis is not complex enough to realize that foo() != foo() is a precondition to the entire while loop condition being true). Thus, the compiler errs on the side of assuming that the access could happen without prior initialization and emits the warning.
So it's an engineering trade-off. You could report the bug, but if you do, I suggest you supply a more compelling real-world example of idiomatic code to argue in favor of making the analysis more complex. Are you sure you can't restructure your original code to make it more approachable to the compiler, and more readable for humans at the same time?
I did some experimenting with VC++2017 Preview.
It's definitely a bug bug. It makes it impossible to compile and link code that might be correct, albetit smelly.
A warning would be acceptable. (See #SebastianRedl answer.) But in the latest and greatest VC++2017, it is being treated as an error, not warning, even with warnings turned off, and "Treat warnings as errors" set to No. Something odd is happening. The "error" is being thrown late - after it says, "Generating code". I would guess, and it's only a guess, that the "Generating code" pass is doing global analysis to determine if un-initialized access is possible, and it's getting it wrong. Even then, you should be able to disable the error, IMO.
I do not know if this is new behavior. Reading Sebastian's answer, I presume it is. When I get any kind of warning at any level, I always fix it in the code, so I would not know.
Jesse, click on the triangular flag near the top right of Visual Studio, and report it.
For sure it's a bug. I tried to remove it in all possible ways, including #pragma. The real thing is that this is reported as an error, not as a warning as Microsoft say. This is a big mistake from Microsoft. It's NOT a WARNING, it's an ERROR. Please, do not repeat again that it's a warning, because it's NOT.
What I'm doing is trying to compile some third party library whose sources I do not want to fix in any way, and should compile in normal cases, but it DOESN'T compile in VS2017 because the infamous "error C4703: potentially uninitialized local pointer variable *** used".
Someone found a solution for that?
I try to build CRF++ in Visual Studio 2013 and get this error in the last line:
array_[begin + siblings[i].code].base =
value_ ?
static_cast<array_type_>(-value_[siblings[i].left]-1) :
static_cast<array_type_>(-siblings[i].left-1);
error C4146: unary minus operator applied to unsigned type, result
still unsigned
Specifically, it is in darts.h, line 189.
I built again in Visual Studio 2015 then there is no error.
How can I fix this in Visual Studio 2013?
C4146 is not supposed to be an error. It is a mere warning. If you see it as an error in your case, it means that someone has configured it this way, most likely unintentionally. This makes no sense.
Find and undo the changes that turned it into an error. Then you can disable it if you wish.
For others I wanted to add another answer in case they stumble into that bug like me.
Even if "Threat warning as error" was off in my compiler, I had to compile my project with #pragma warning(disable:4146) in my header's file that was showing me the error. For you it would had been inside darts.h
Please note disabling the warning globally in my project was not working (compiler /wd4146), the pragma line was needed in the header's file directly.
the siblings variable also has unary minus applied to it, maybe that is the culprit? Also if it's templated code you cannot really be sure value_ is going to be be short, int or long unless that is asserted via static_assert or so. We can only guess as you don't provide information about what types are actually used or something reproducable. Also did you use the exact same project for compilation in VS2015? If not, the warning might just have been disabled there.
Anyway, suppose it is a bug in VS2013, it likely won't ever get fixed anymore so you can try to find a workaround. Start by breaking that statement down into smaller ones until you know exactly which part is the problem (or maybe, by then the problem is gone already as it goes with compiler bugs). Then suppress the warning with #pragma warning ( disable : 4146 ), wrapped in a conditional directive so it only has effect for VS2013 #if _MSC_VER > 1800 && _MSC_VER < 1900 should do fine. Enable the warning again after the statement. Add a comment as to why the warning is disabled and submit the changes as a patch to CRF++.
Try this:
int tmp = static_cast<int>(siblings[i].left);
array_[begin + siblings[i].code].base =
value_ ?
static_cast<array_type_>(-value_[siblings[i].left]-1) :
static_cast<array_type_>(-tmp - 1);
For anyone running into the really confusing part of this:
This isn't supposed to be an error. In fact, there are a bunch of warnings that Visual Studio incorrectly turns into errors by default. Compilers can add warnings for whatever they want, but throwing errors for valid code is just a bug.
The culprit is the "SDL checks" option. It's known for adding things like runtime stack checking, which is fine, but they snuck a bit of nastiness in: "and enables extra security-relevant warnings as errors". That needs to be turned off to have something slightly closer to a standard C++ compiler.
Is there a way, in VC++ (VSTS 2008), to froce a compiler error for functions that do not explicitly return a value on the default return path (Or any other quick way to locate them)?
On the same issue, is there any gaurentee as to what such functions actually return?
I don't know exactly the warning number, but you can use #pragma warning for enforcing a specific warning to be treated as error:
Example:
#pragma warning( error: 4001)
will treat warning 4001 as error
If you enable max warning level, and treat warnings as errors, you'll surely find what you're looking for. A guess as to what will be returned otherwise: A default-constructed object of the function's return type.
VC will warn about many instances of this problem, but fails to detect some. I've repeatedly caught it missing this problem in function templates, but I've seen int in some plain functions, too. Treating warnings as errors (compiler switch for all warnings or pragma for specifc ones) will make it impossible to overlook those it finds.
For those VC overlooks you have to use more thorough tools. AFAIK in VSTS you can also throw an /analyze switch for the compiler and have it find even more problems.
There's also many versions of lint-like programs.
Using some other compiler helps, too. Porting a VS project to GCC for the first time can be quite hard, but I think Intel's compiler can be used as a drop-in replacement for VC and compile VC projects right away. Comeau C++, too, has switches for being quite VC-compatible and has incredibly good errors messages.