Resources listing known compiler bugs in VC++ 6.0 - visual-studio

Is there a resource listing CString fixes between VC6.0 and Visual Studio 2010. We have encountered what appears to be a compiler bug in VC6.0 sp6 that works in 2010.
I'm working to distill it into a small test case but essentially in cases where ~300 strings are referenced two nearly identical strings resolve such that one is lost at the assembly level. Seems like a possible internal hash table collision internal to vc6.0.
I need to prove this for a vc6.0 work around solution. (Our legacy code is vc6.0). I'll try to post a code snippet once I can / (if I can ) distill it to something I can post.

Visual C++ uses COMDAT naming to support the /GF string pooling flag (which is implied by /ZI) However, under VC++6.0 the symbol name length was truncated to 256 characters.
I suspect your strings have identical prefixes up to the 256th character.

Related

Why does the Tool Help Library offer 2 versions of same functions/structures?

I've noticed that the Tool Help Library offers some functions and structures with 2 versions: normal and ending with W. For example: Process32First and Process32FirstW. Since their documentation is identical, I wonder what are the differences between those two?
The W and A versions stand for "wide" and "ANSI". In the past they made different functions, structures and types for both ANSI and unicode strings. For the purpose of this answer, unicode is widechar which is 2 bytes per character and ANSI is 1 byte per character (but it's actually more complicated than that). By supplying both types, the developer can use whichever he wants but the standard today is to use unicode.
If you look at the ToolHelp32 header file it does include both A and W versions of the structures and functions. If you're not finding them, you're not looking hard enough, do an explicit search for the identifiers and you will find them. If you're just doing "view definition" you will find the #ifdef macros. If you still can't find them, change your character set in your Visual Studio project and check again.
Due to wide char arrays being twice the size, structure alignment will be incorrect if you do not use the correct types. Let the macros resolve them for you, by setting the correct character set and using PROCESSENTRY32 instead of indicating A or W, this is the preferred method. Some APIs you are better off using the ANSI version to be honest but that is something you will learn with experience and have to make your own decision.
Here is an excellent article on the topic of character sets / encoding

Swap text blocks in Visual Studio

Is there any built-in way to swap two arbitrary text blocks in Visual Studio? (I happen to be using VS2015).
Example: you have a method such as FooBar(target, source) and you decide it would make more sense to be FooBar(source, target). If you've called FooBar in a lot of places you might need to run multiple operations to swap the various pairs of variable names.
Having this done also within comments could also be useful.
While obviously you could do this with multiple search & replaces, or multiple Edit->Refactor->Renames (^R^R), those approaches are somewhat prone to error, and are more tedious.
If this doesn't actually exist within Visual Studio but another tool like Notepad++ (for instance) has this capability, that is almost as good.
These questions are similar but for more specific scenarios:
Does anyone know a visual studio keyboard short cut to swap around two sides of a statement?
Invert assignment direction in Visual Studio
Visual Studio has the built in functionality to reorder parameters. You can select this by using Edit > Refactor > Reorder Parameters.... Changing parameters in this form will update all the method calls in addition to the method. You can also request to preview all the changes which will be made.
More information here.

GNU C++ import name mangling [duplicate]

I came across an interesting error when I was trying to link to an MSVC-compiled library using MinGW while working in Qt Creator. The linker complained of a missing symbol that went like _imp_FunctionName. When I realized That it was due to a missing extern "C", and fixed it, I also ran the MSVC compiler with /FAcs to see what the symbols are. Turns out, it was __imp_FunctionName (which is also the way I've read on MSDN and quite a few guru bloggers' sites).
I'm thoroughly confused about how the MinGW linker complains about a symbol beginning with _imp, but is able to find it nicely although it begins with __imp. Can a deep compiler magician shed some light on this? I used Visual Studio 2010.
This is fairly straight-forward identifier decoration at work. The imp_ prefix is auto-generated by the compiler, it exports a function pointer that allows optimizing binding to DLL exports. By language rules, the imp_ is prefixed by a leading underscore, required since it lives in the global namespace and is generated by the implementation and doesn't otherwise appear in the source code. So you get _imp_.
Next thing that happens is that the compiler decorates identifiers to allow the linker to catch declaration mis-matches. Pretty important because the compiler cannot diagnose declaration mismatches across modules and diagnosing them yourself at runtime is very painful.
First there's C++ decoration, a very involved scheme that supports function overloads. It generates pretty bizarre looking names, usually including lots of ? and # characters with extra characters for the argument and return types so that overloads are unambiguous. Then there's decoration for C identifiers, they are based on the calling convention. A cdecl function has a single leading underscore, an stdcall function has a leading underscore and a trailing #n that permits diagnosing argument declaration mismatches before they imbalance the stack. The C decoration is absent in 64-bit code, there is (blessfully) only one calling convention.
So you got the linker error because you forgot to specify C linkage, the linker was asked to match the heavily decorated C++ name with the mildly decorated C name. You then fixed it with extern "C", now you got the single added underscore for cdecl, turning _imp_ into __imp_.

F# Option goes bonkers when copying the solution to a different location

This is extremely strange, and I'm hoping someone will have some insights to make sense of this.
I have an F# 2.0 (Visual Studio 2010, targeting .Net 4.0) solution which works fine in the location where I originally created it, but if I try and copy it to a new folder (because I want to check it in to source control), I get some very odd errors when building. They tend to be along the lines of:
error FS0803: Invalid use of a type name and/or object constructor. If necessary use 'new' and apply the constructor to its arguments, e.g. 'new Type(args)'. Overloads are: None() : unit.
or
error FS0001: This expression was expected to have type obj option but here has type Some<'a>
These errors are only occurring for uses of the option type, a simple example of one such usage being:
let asOption e =
match e with
| null -> None
| _ -> Some(e)
Now, remember, this is a solution that compiles just fine in its original location. I've tried the obvious like Clean/Rebuild, deleting the obj and bin directories, restarting Visual Studion, and still, the same.
The reference DLLs are all the same in both cases, GAC'd DLLs are being referenced from the GAC, non-GAC'd dlls are copied and being referenced from the same relative path. Just for fun, I've even compared the output window text of the calls to Fsc.exe used to compile each solution to ensure the compiler is being called with the same arguments in both cases, and, naturally, it is.
Anyone have any idea of what may be causing this? Am I getting some strange limbo version of FSharp.Core.dll out of the GAC somehow? Am I just the most unlucky of the unlucky stiffs?
So the weird symptom had an equally weird cause.
It turns out one of the DLLs I was referencing (the ubiquitous "Core" junk-drawer dll every project has) must have some extension methods in place that are causing some issues with the type inference used by the compiler and visual studio.
When I remove the open MyProject.Core and replace any of the references to types I'm using with the fully qualified name, the strange errors magically go away.
So, at this point, two questions remain:
What kind of insane extension methods are in there that could be causing this
Why was the original solution/project unaffected by this? (I'm guessing this may be related to the order in which the references were passed into the call to Fsc.exe...but I'm not sure).
I may actually dig in enough to try and figure out the answer to #1. I'm not sure if it is exposing some sort of bug with the F# compiler (doubtful), or if my co-workers are just doing something unnatural with extension methods (highly likely)
UPDATE:
Looks like someone had some F# envy and created an Option<T> class in the Core project. Pretty much explains things. I've not experimented to see if the order of the includes on the Fsc.exe call make a different, but I have a feeling that is it.
References should almost never come from the GAC, they should come from Reference Assemblies. Post the fsc.exe command-line you are witnessing, perhaps it will shed more light. I am guessing the FSharp.Core reference is messed up somehow (perhaps related to the sigdata/optdata files that stand alongside its reference assembly?)
(Points for a very weird symptom, though!)
Assuming F# compiler is deterministic, there obviously must be some difference in how it is being invoked, perhaps in the environment variables. Have you tried running MSBuild from the command line? It usually helps with these kind of things.
One guess of what's going on is that F# infers different types for your code. Have you tried constraining it a bit to only have to deal with simple types? For example:
let asOption (e: obj) =
match e with
| null -> None
| _ -> Some(e)
Or else:
let asOption<'T> (x: 'T) : option<'T> =
if x :> obj = null then None else Some x
The later gets rid of the null constraint on the generic parameter.

"deleting" copy ctor/assignment in C++11

In VS 2010 SP1, the following:
class Foo
{
public:
Foo() { }
Foo(Foo const&) = delete; // Line 365
Foo& operator=(Foo const&) = delete; // Line 366
};
does not compile. It complains:
CPPConsole.cpp(365): error C2059: syntax error : ';'
CPPConsole.cpp(365): error C2238: unexpected token(s) preceding ';'
CPPConsole.cpp(366): error C2059: syntax error : ';'
CPPConsole.cpp(366): error C2238: unexpected token(s) preceding ';'
Is this not supported yet? The strange thing is, Intellisense seems to recognize this construct. It says "IntelliSense: function "Foo::operator=(const Foo &)" (declared at line 366) cannot be referenced -- it is a deleted function"
What am I missing?
VS 2010 has something of a dual personality. Specifically, it actually has two entirely separate compiler front ends.
When you compile the code, that's done with Microsoft's own compiler, which goes all the way back to MS C 3.0 for MS-DOS, released ~3 decades ago (in case you're wondering why it was 3.0, MS sold a re-labeled version of Lattice C before that).
Up until VS 2008, the parsing in the IDE was rather primitive compared to the compiler's, so it didn't parse a lot of more sophisticated C++ quite correctly. They decided that was unacceptable, and rather than try to upgrade the IDE's existing parser to match the compiler's, they licensed the EDG compiler front-end.
This gives more or less the opposite situation: the IDE's parser for Intellisense is now considerably closer to conforming than the one on the compiler, and recognizes a fair number of C++0x constructs that the compiler doesn't.
There's a little more to the story than just that though: the EDG compiler front-end supports a switch to make it act more like VC++, including emulating a fair number of VC++ bugs. Although I don't have data to confirm it, my assumption would be that Microsoft uses that capability. Since that's based on EDG taking the VC++ compiler, and emulating its bugs, it's probably a fair guess that (at least usually) EDG's VC++ emulation will run about a version behind VC++ itself. That gives the somewhat paradoxical situation where EDG (in normal use) is normally quite a bit ahead of VC++, but the version MS uses in the IDE is probably doing to be at least slightly behind most of the time.
It isn't implemented yet in VS2010.

Resources