I'm using visual studio 2017 and I noticed that I don't get syntax error warnings when using template, for example:
and when I remove the template I get this:
and this:
Is it possible to fix this?
code(not image):
template<int a>
void noErrors()
{
sleiudbg;sg ojrp jabp srpghs //some gibberish
}
template<int b>
void noErrors(string s)
{
int p = s.Size();
}
Oh please, must we post code only as images? Please fix that, it means I cannot experiment with your code.
But the answer to your question is that the incremental syntax checker built into the IDE is of limited intelligence, especially where templates are concerned (where detecting and reporting compiler errors in general is a complex business) and as a result a great deal of stuff which is not going to compile slips through.
The compiler, on the other hand, will throw this out straightaway, and also report errors resulting from an invalid instantiation of a template in a moderately helpful way (although such error messages are never the easiest things to read).
And can you change any of this? Sorry, no, (unless you can persuade Microsoft to beef-up their IDE).
where error checking is a complex business - more here:
What does a compiler check for uninstantiated template code?
Related
I'm working with some code that uses elaborate template metaprogramming to "assert" on variable equalities/inequalities at compile-time, hacking the compiler's error messages to display the values seen by the compiler on each side of the test.
So for a simplified, not-NDA-breaking example, you might have:
template<bool>
struct test
{
};
template<>
struct test<true>
{
using result = char;
};
template<int x, int y>
struct CheckEqual
{
typedef typename test<x == y>::result result;
}
CheckEqual<sizeof(int), sizeof(char)>::result equality; // Example assertion declaration
This example will print out a complicated error message, and somewhere in there will be the template declaration seen by the compiler, test<4, 1>.
My goal is to make this more readable, since "[result] is not a member of test<number, number>" isn't too easy to associate with specific files/callsites. I've tried replacing the tests with static_assert invocations, and the suggestion was knocked back because the compiled values of x and y would stop showing up in the output.
Afterwards I attempted to do something clever with character parameter-packs, constexpr and static_assert, hoping that I could construct a readable error message that included the compiled values of each argument. That failed when I realized that static_assert only takes string literals.
What I'm thinking now is that Visual Studio has #error for pre-processor messages and OutputDebugStringW/A for runtime messages, so it must have some sort of compiler extension for output during compilation - I'm wondering if anyone knows what might be. What I would love is something that behaves like static_assert, but allows for variable as well as literal output.
My goal is to emit an error and output a string at compile time reading "Assertion failed; [x] ([compiled value of x]) != [y] ([compiled value of y])".
I'm aware a VS-specific extension will be non-portable, but for now I'm not really concerned - so long as this works on some PCs, its better than nothing. Future versions can use extensions for GCC, clang, etc.
I'm updating a huge legacy system, and am currently stumped by the following function:
template <class EL>
EL& FastInsertVector<EL>::operator[](size_type index)
{
return (EL&) FastInsertVectorBase::operator [][](index);
}
MS VC++ 2022 compiles it happily, whereas C++ Builder 11.1.5 rejects it saying:
expected expression
If I remove the second set of [], both compilers are happy. Unfortunately, this is shared code that both compilers must be able to handle.
This codebase is huge, and has no tests, and I'm having difficulty actually understanding what this syntax even means.
Is this valid C++ syntax? Can anyone explain what it's trying to express?
Is there a patch out there (official or unofficial) to get IntelliSense to stop reporting every use of decltype as a syntax error? It compiles fine, so I know decltype is supported, but it's very distracting seeing red squiggles everywhere and makes it much harder to find actual errors in the code. Every compile gives me a list of hundreds of non-errors - basically at least 3 for every use of decltype in the code base, e.g.:
std::for_each(std::begin(list), std::end(list), [](const decltype(list)::value_type& item)
{
<do stuff with item>
});
will produce the following (non) errors:
IntelliSense: global-scope qualifier (leading '::') is not allowed
IntelliSense: expected a ')'
IntelliSense: identifier "item" is undefined
Upgrading to VS2015 is not an option at this point. (I doubt I could convince the company to shell out to upgrade every computer, and upgrading only some of them would lead to backwards compatibility issues.)
Personally, I'd prefer not to use decltype at all until we get an IDE that fully supports it (there's nowhere I know of that you actually need it), but I don't think I can convince everybody of that either. I just want to make all those fake errors go away so that I can find the real ones without poring over thousands of false-positives.
Given a helper template alias
template <typename T> using id = T;
you can avoid the Intellisense errors, while still keeping the code perfectly valid, by writing id<decltype(list)>::value_type where you would otherwise have written decltype(list)::value_type.
Depending on how often decltype is immediately followed by ::, you may want to create a macro as simple as:
#define DECLTYPE(x) id<decltype(x)>
When use Eclipse with MinGW(version:4.8.1) to compile the following code fragement, it can pass but Eclipse still report:
"Multiple markers at this line - Type 'alignas' could not be resolved"
template<typename X> void set_aside(std::vector<X> vx) {
constexpr int max_buf = 1024;
alignas(X) X buffer[max_buf];
int max = min(vx.size(), max_buf / sizeof(X));
std::uninitialized_copy(vx.begin(), vx.begin() + max, buffer);
}
What happend with this issue, although the code fragement pass the comiple,yet Eclipse marks with error.
Someone have ever met this issue? Please kindly help me to resolve this issue,thanks very indeed!
Many IDEs use a front-end syntax checker that is different than their back-end compiler. Eclipse Kepler (released June 2013) is mostly up-to-date with C++11 syntax, although some things like alignment support and the interaction with in-class initializers and default constructors might not be fully supported (yet). Similary, C++14 features like decltype(auto) will work if the back-end compiler is called with std=C++1y but will not be recognized by the front-end syntax checker.
NOTE: this is not unique to Eclipse, also Visual C++ Intellisense is sometimes running behind (especially in CTP versions) the actual compiler, causing the red squiggly lines.
I have a piece of code that pretty much reduces down to:
template<class T> struct MyStruct; // No definition by default
template<class T> struct MyStruct<T *> { ... }; // Specialization for pointers
Now somewhere in my code, I'm getting an instantiation of MyStruct<T> that happens to be undefined (no C++0x/011, no Boost... nothing fancy, just plain C++03):
error C2027: use of undefined type 'MyStruct<T>'
The trouble is, I have no idea where this is being caused, because the code that's doing the instantiation is itself a template, and called from numerous places, with different arguments.
Is there a way to somehow figure out what T is at compile-time, so I can understand the error messages better?
(Sorry, I forgot to mention: Visual Studio 2008.)
I believe you're using MSVC++, if so, then see the output window, it might have more info printed, especially the line number along with the filename. Once you know the file and line number, you can start from there.
Output window usually prints everything, like how and with what template argument(s), a template is instantiated. Everything step by step. Those messages are very useful when debugging.
As you found yourself, enabling /WL prints more detail messages in the output window.
I know you said no C++11, but you may want to consider, since C++03 code is backwards compatible in all C++11 compliant compilers, to use the static_assert feature of C++11 to debug your code ... if you must do the final compile with a C++03 compiler, then you can always create a #define and use the #ifdef and #endif pre-processor macros to make sure that the static_assert feature does not cause problems in earlier compilers that do not support C++11 features.
See the MSDN docs here for more info.