Hi!

I've had this problem for a couple of days now, and I don't know what it is. My Visual Studio 2012 project worked perfectly before, but now it just hangs at the "Generating code..." part. It litteraly takes forever. I once left it for more than 30 minutes, and it was still there at the point I left it.
It builds until this part (though not very quickly):

1>------ Build started: Project: Interactive Quiz, Configuration: Release Win32 ------
1>Build started 28-Apr-13 13:16:56.
1>InitializeBuildStatus:
1>  Touching "Release\Interactive Quiz.unsuccessfulbuild".
1>GenerateTargetFrameworkMonikerAttribute:
1>Skipping target "GenerateTargetFrameworkMonikerAttribute" because all output files are up-to-date with respect to the input files.
1>ClCompile:
1>  All outputs are up-to-date.
1>  AssemblyInfo.cpp
1>  Interactive Quiz.cpp
1>c:\users\boris\google drive\fit\vs projects\interactive quiz\interactive quiz\registerForm.h(93): warning C4018: '<' : signed/unsigned mismatch
1>c:\users\boris\google drive\fit\vs projects\interactive quiz\interactive quiz\registerForm.h(486): warning C4244: '=' : conversion from 'std::streamoff' to 'int', possible loss of data
1>c:\users\boris\google drive\fit\vs projects\interactive quiz\interactive quiz\quizForm.h(3641): warning C4018: '<' : signed/unsigned mismatch
1>c:\users\boris\google drive\fit\vs projects\interactive quiz\interactive quiz\editQuestions.h(476): warning C4018: '<' : signed/unsigned mismatch
1>c:\users\boris\google drive\fit\vs projects\interactive quiz\interactive quiz\editQuestions.h(794): warning C4018: '<' : signed/unsigned mismatch
1>c:\users\boris\google drive\fit\vs projects\interactive quiz\interactive quiz\editQuestions.h(1045): warning C4800: 'void *' : forcing value to bool 'true' or 'false' (performance warning)
1>c:\users\boris\google drive\fit\vs projects\interactive quiz\interactive quiz\chooseSubject.h(160): warning C4018: '<' : signed/unsigned mismatch
1>c:\users\boris\google drive\fit\vs projects\interactive quiz\interactive quiz\introForm.h(366): warning C4018: '<' : signed/unsigned mismatch
1>  QuizForm.cpp
1>c:\users\boris\google drive\fit\vs projects\interactive quiz\interactive quiz\quizForm.h(3641): warning C4018: '<' : signed/unsigned mismatch
1>  aboutForm.cpp
1>  chooseSubject.cpp
1>c:\users\boris\google drive\fit\vs projects\interactive quiz\interactive quiz\QuizForm.h(3641): warning C4018: '<' : signed/unsigned mismatch
1>c:\users\boris\google drive\fit\vs projects\interactive quiz\interactive quiz\chooseSubject.h(160): warning C4018: '<' : signed/unsigned mismatch
1>  creditsForm.cpp
1>  editQuestions.cpp
1>c:\users\boris\google drive\fit\vs projects\interactive quiz\interactive quiz\editQuestions.h(476): warning C4018: '<' : signed/unsigned mismatch
1>c:\users\boris\google drive\fit\vs projects\interactive quiz\interactive quiz\editQuestions.h(794): warning C4018: '<' : signed/unsigned mismatch
1>c:\users\boris\google drive\fit\vs projects\interactive quiz\interactive quiz\editQuestions.h(1045): warning C4800: 'void *' : forcing value to bool 'true' or 'false' (performance warning)
1>  loginForm.cpp
1>  registerForm.cpp
1>c:\users\boris\google drive\fit\vs projects\interactive quiz\interactive quiz\registerForm.h(93): warning C4018: '<' : signed/unsigned mismatch
1>c:\users\boris\google drive\fit\vs projects\interactive quiz\interactive quiz\registerForm.h(486): warning C4244: '=' : conversion from 'std::streamoff' to 'int', possible loss of data
1>  Generating Code...
1>c:\users\boris\google drive\fit\vs projects\interactive quiz\interactive quiz\registerform.h(114): warning C4715: 'InteractiveQuiz::registerForm::extractWord' : not all control paths return a value
1>c:\users\boris\google drive\fit\vs projects\interactive quiz\interactive quiz\editquestions.h(1106): warning C4715: 'InteractiveQuiz::editQuestions::isEverythingFilled' : not all control paths return a value
1>c:\users\boris\google drive\fit\vs projects\interactive quiz\interactive quiz\editquestions.h(497): warning C4715: 'InteractiveQuiz::editQuestions::extractWord' : not all control paths return a value
1>c:\users\boris\google drive\fit\vs projects\interactive quiz\interactive quiz\quizform.h(3662): warning C4715: 'InteractiveQuiz::quizForm::extractWord' : not all control paths return a value
1>c:\users\boris\google drive\fit\vs projects\interactive quiz\interactive quiz\choosesubject.h(181): warning C4715: 'InteractiveQuiz::chooseSubject::extractWord' : not all control paths return a value

I don't know what it could be? I read how some people talked about the "slow build" problem, that I could go to Tools > Options > Projects and Solutions > Build and Run and then change something there, but the thing is that my build isn't just slow, it's infinitely slow, it just stops there!

It all worked well until, I think, about April 19th, but all I did was edit certain parts of code. Even after that, I think it worked pretty well, when suddenly it just got stuck at the Generating code... part.

EDIT: Let me just say, before you rush with it - all of these 'errors' like not all control paths return a value or conversion from std::streamoff to int, possible loss of data, etc. have existed before and my project could build normally, without any errors or problems; it's just that now it won't work!

Any ideas? Thanks.

Edited 3 Years Ago by boris90

Show us the code (and yes, fix the warnings - the ones about not every control path returning a value are actually pretty serious and even if it did build, it was broken, and you'd generated some kind of mutant frankencode).

It is quite possible to write code that a compiler will happily spend infinity trying to build for you.

Edited 3 Years Ago by Moschops

Thanks, Moschops... but my code is really large. Several header files with the code for the Windows GUI application. The largest file I've got is a QuizForm.h file which is almost 2.5 MB and it has 81875 lines of code! So anyway, I don't really know what to show you out of all this code within this 2.5 MB file itself, not to talk about other header files (the second biggest header file is just 40 KB, though).

The point is, I won't be able to give you the whole code here, so if you know anything about the errors you saw above, that'd be helpful.

Thanks!

You're certainly ticking all the boxes so far. Huge amounts of unwieldy code, the compiler screaming at you that you're doing a lot of things that are really bad ideas. I do know that if the compiler is telling you something is a bad idea, and you do it anyway, and the compiler ends up in an infinte loop, you should stop doing what it told you was a bad idea.

Yeah, I know that you've got away so far with implementing some kind of frankencode that's not even C++ that the compiler is desperately trying to bash into shape for you. Don't be surprised that it finally broke.

In all seriousness, fix the warnings first. They exist for a reason. Some of them don't matter so much. Some of them are telling you that your code is not even C++.

Edited 3 Years Ago by Moschops

QuizForm.h file which is almost 2.5 MB and it has 81875 lines of code!

OMG! Why??? Maybe you need to rethink what you have in that header file. There should not be any executasble code (such as functions) unless it's inline code. Zip it up and attach it to your post so that we can see what you did. If you don't want to make it public then you can email the zipped file to me and I'll take a look (not promosing any results though).

Hey, Ancient Dragon! I'll do it, I'll attach the code soon, but I can't now since I'm not at home currently. Hopefully, someone will be able to help me with this... I'm so desperate.

The largest file I've got is a QuizForm.h file which is almost 2.5 MB and it has 81875 lines of code!

Absolutely insane! I'm speechless. You've let this get way out of hand. You should never have so much code in one file, let alone a header file. A few thousand lines is already excessive, 80 thousand is insane.

Clearly, it seems that you are not using C++'s separate compilation model to your advantage. Generally, in C++, you compile many small source files (cpp files) separately (which know about each other's functions and classes through included header files), and then linked them together at the end, or package them inside static or dynamic libraries. Doing this makes compilation much much faster because the compiler never has to deal with more than a small portion of the overall code, and you only have to re-compile the small parts that have changed when you changed them. Clearly, you seem to be doing the opposite, and you are now suffering the consequences of that.

One possible cause of your problems is simply that the code is too big. You might want to monitor the amount of memory being used by the compiler when compiling your code. Sometimes, if the compiler reaches an out-of-memory condition while running (i.e., it has too much code to analyse), it just slows down tremendously, possibly to the point that it will effectively never finish. I've had that problem before with very heavily templated code where the amount of code being generated (from instantiating the templates) was so big that the compiler would reach an out-of-memory condition, which doesn't always make it crash, it just makes it slow down to the point that it doesn't really do anything anymore. One cause of that, for example, is that much of the work that a compiler does is create hash-tables of all the identifiers (classes, functions, variables, etc.) in the code such that it can look them up quickly when looking at code the refer to these identifiers. A look-up in a hash-table is done in constant-time (O(1)). But if the compiler is denied the required memory to create / expand the hash-tables, it can fall-back to an un-indexed look-up method (i.e., linear search) that requires no extra memory but it also means that look-ups require O(N) time, effectively throwing the compiler in a downward spiral of assinine performance and leaving it in a rot from which it will probably never work its way out of (at least, not within a reasonable amount of time).

If I presume that the reason you have so much code in a header file is because your code is templated, then you should be aware that there are many things you can do with templates that will throw the compiler into an infinite loop. If you have any kind of recursive template instantiations, then check to make sure they don't constitute an infinite instantiation loop. Most compilers have what is called an "instantiation depth limit" which guards against that problem, however, it is also possible that the compiler runs out of memory (as said above) before it hits that point.

Let me just say, before you rush with it - all of these 'errors' like not all control paths return a value or conversion from std::streamoff to int, possible loss of data, etc. have existed before and my project could build normally, without any errors or problems; it's just that now it won't work!

These warnings are serious. You must deal with them. This is not even debatable. What you are doing right now is building a house of cards, and arguing that it seems to hold, but that's only because there hasn't been much wind blowing on it just yet. When the compiler tells you that some control paths don't return a value, this means that under some circumstances (maybe that you haven't encountered in your tests yet) the code will end up returning an uninitialized value, most likely wreaking havoc at the call-site. The other warning may be considered less serious, but one of the points of getting rid of all warnings is so that you don't miss the really important warnings, that would otherwise be drowned in a sea of less-serious warnings.

Long story short: Fix those warnings!

It all worked well until, I think, about April 19th, but all I did was edit certain parts of code.

Great! If you know the date when things started to go wrong, then you can just use your version control system to revert code back to a day when it was working, and then incrementally examine each of the changes made since to see where the root of the problem is. Or did you not use version control? (slightly rhetorical) If not, you're in trouble. Writing what seems to be a large project (in the hundreds of thousands of lines) without version control is another thing that would qualify as insanity. Even if you work alone, the reason for using version control is in case that one day you hit a snag like you did, at which time, having a complete history of the daily revisions to the code is a life-saver.

Any ideas? Thanks.

There is always the possibility that the compiler has a bug (which isn't too far fetched for teh Microsoft compiler, although 2012 should be reasonably good). To test that, you should compile the code with another compiler (e.g., GCC). However, if this is a Windows GUI programmed in Visual Studio, this is most likely not an option, you're stuck with the Microsoft compiler (MSVC) for better or worse.

So, to summarize, the likely sources of your error are (in order of likelihood):

  1. A compile-time computation that throws the compiler in an infinite loop. For example, a recursive template instantiation that is infinite.
  2. You are just compiling too much code at once and the compiler is running low on memory, causing a tail-spin of performance degradation to the point that it never gets out.
  3. There is a bug in the compiler.

And, here is your to-do list:

  1. Take care of all the warnings that the compiler reports (under maximum warning levels).
  2. Split the code into smaller files, and into cpp files as much as possible, and use the separate compilation model to your advantage.
  3. Check each header file to make sure you are not needlessly including other headers that are not specifically needed in that particular header file. A tool you can use for that is "include-what-you-use".
  4. Adopt a version control software (if you haven't done so already). I recommend Git.

Doing the above will, I think, probably fix your problem, and if it doesn't, you should be able to see where the error comes from much more easily once the code is split into more reasonable chunks (i.e., if you compile 80 chunks of 1,000 lines, only one of them, if any, will hit this "infinite compilation" issue, and then, you have only 1,000 lines to examine, instead of 80,000). And if the problem still persists after all that, then look into the possibility that the compiler has a bug.

P.S.: One broader lesson here is that what might have worked for you in the past on small projects (e.g., no version control, putting all the code in large header files, including all standard header files everywhere, ignoring warnings, etc.) does not scale to larger projects and if you keep on going, you will hit a wall and you might be forced to throw all that code away due to not being able to ever refactor all of it nor being able to maintain it. In other words, it becomes less of an effort to code everything again from scratch (maybe copy-pasting some code) than it is to either refactor the current code or keep on going with the code as it is and suffer from all its flaws. I know, this has happened to me before, and it's painful. I hope you haven't hit that wall yet, but it seems like it will require a lot of effort to get out of this problem. I really hope it is not as bad as it appears from my vantage point.

Gosh, Mike, thanks for such a detailed post! I really appreciate it! I've read it now and I've understood what you meant. After all, that's what my assistant in my faculty told me to do, 'always spread an application into more code chunks'. I knew that, but putting puzzle pieces together in programming can be, sometimes, so addictive that you actually find yourself saying 'Oh, I just need to add this piece of code and I'll have what I need'. Indeed, I really do need pretty much all the header files that I've included, but I'll revise them all and see if I can break the code into more chunks, but I'm afraid I don't have much time, because the application I'm working on is my bachelor's thesis work (and now I'm working on writing the document, diagrams and a PPT presentation).

As of the code Ancient Dragon asked for, I'll post it in my next post, when it is uploaded.

Edited 3 Years Ago by boris90

OK, here it is.

Download

Just click the Interactive Quiz.rar underlined text in the title and the download should start.

Thanks everyone for so much effort, I'll repay you all somehow ;)

Well, it appears you have two functions here: quizForm::quizForm_Load and quizForm::btnSubmitTest_Click. The first function has 14,243 LOCs and the second function has 35,154 LOCs. My code editor had trouble just doing the copy-paste operations on such large files, I wouldn't imagine a compiler would have an easier time with it.

Before I say anything else, your code is in C++/CLI, this is a different programming language, not C++. (regardless of how much it tries to look like it is) It is more closely related to C# than to C++.

First, those two functions need to be in the cpp file, there is absolutely no reason to have them in the header file. If you don't know how to do that (as I see that you haven't put anything into any of the cpp file in your project folder), then, here it is:

QuizForm.cpp:

#include "stdafx.h"
#include "quizForm.h"


namespace InteractiveQuiz {

System::Void quizForm::btnSubmitTest_Click( System::Object^  sender, System::EventArgs^  e ) {
  // insert all the content of the function here. Just cut-paste, no need to change anything. 
};

System::Void quizForm::quizForm_Load( System::Object^  sender, System::EventArgs^  e ) {
  // insert all the content of the function here. Just cut-paste, no need to change anything.
};

};

and then, in the header file (in the class declaration), you leave only the declarations:

public ref class quizForm : public Form {

   // ... all the stuff ...


    // only the declarations of the Load and SubmitTest functions:

    System::Void quizForm_Load( System::Object^  sender, System::EventArgs^  e );
    System::Void btnSubmitTest_Click( System::Object^  sender, System::EventArgs^  e );
};

You can even put each function in its own cpp file if you want, given how big they are.

Second, those two functions are massive works of copy-pasting. I have counted many entire blocks of code that are copy-pasted verbatim more than 20 times within the function. This is insane. When you program, any time you start copy-pasting code around, you should immediately think of a way to put that code segment in a separate function. It's better to call a function 20 times than having 20 times the same piece of code. With proper refactoring, I think those functions could be reduced in size by a factor of 10 to 20, easily. That would bring them to a code-line count around 1,000 to 2,000 LOCs each, including a few helper functions. That's much more reasonable.

Third, you need to learn about arrays. Here, on Daniweb, we sometimes get questions that look like this:

"I'm trying to sort integer values, here is my code:"

#include <iostream>
using namespace std;

int main() {
  int x1, x2, x3, x4;

  cout << "Please enter four numbers: ";
  cin >> x1 >> x2 >> x3 >> x4;

  if( x1 > x2 ) {
    int tmp = x1;
    x1 = x2;
    x2 = tmp;
  };
  if( x2 > x3 ) {
    int tmp = x2;
    x2 = x3;
    x3 = tmp;
  };
  if( x3 > x4 ) {
    int tmp = x3;
    x3 = x4;
    x4 = tmp;
  };
  if( x1 > x2 ) {
    int tmp = x1;
    x1 = x2;
    x2 = tmp;
  };
  if( x2 > x3 ) {
    int tmp = x2;
    x2 = x3;
    x3 = tmp;
  };
  if( x1 > x2 ) {
    int tmp = x1;
    x1 = x2;
    x2 = tmp;
  };

  cout << "Here is the sorted array:" << endl;
  cout << x1 << " " << x2 << " " << x3 << " " << x4 << endl;

  return 0;
};

Which, of course, is the classic Bubble-sort algorithm applied to 4 values, without using arrays. Obviously, you can't possibly consider scaling up this code to a much larger number of values. And, of course, the scalable code is the following:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
  vector<int> x;

  cout << "Please enter the number of values: ";
  size_t N = 0;
  cin >> N;
  cout << "Please the numbers: ";
  for(size_t i = 0; i < N; ++i)
    cin >> x[i];

  sort(x.begin(), x.end());

  cout << "Here is the sorted array:" << endl;
  for(size_t i = 0; i < N; ++i)
    cout << x[i] << " ";
  cout << endl;

  return 0;
};

The reason why I show this simple sorting example is to make it obvious why you need to use arrays / collections / containers, like std::vector. What your code does is essentially taking the first approach all the way, thus, multiplying the amount of code up to insane proportions.

In your code, you have many "small arrays" of 2 to 8 or so elements (usually strings or GUI objects), and you spell them out as q1, q2, q3, q4, ... and then write an insane amount of copy-pasted code, in the same way as I have done in the sorting example. Then, on top of that, you have all these if-statements, which are also essentially just unrolled loops in which everything is copy-pasted all over. With proper use of containers to avoid that kind of repetition, you could probably collapse these functions down to a few hundred lines at most. And then, if there are any problems with it, the problems will be easy to find and fix.

but I'm afraid I don't have much time, because the application I'm working on is my bachelor's thesis work (and now I'm working on writing the document, diagrams and a PPT presentation).

I hope this is not for a computer science thesis. If I'm gonna be perfectly honest, if anyone is actually supposed to look at your code and evaluate it, I can't imagine that person giving a passing grade for it. I'm sorry to say. The code seems to be a classic case of a nice GUI wrapping, and spaghetti underneath. But then again, GUI code usually looks terrible anyways.

And again, whatever the problem is that doesn't allow this to compile, this is just a case where if you want to find which rope is broken, you have to untie all the knots first (and usually, you find out that the problem wasn't broken rope but the knots themselves). This is why you're not supposed to let it get out of hand like that.

@Mike: I know I did think of using arrays or vectors when I came to this copy-paste part of the code. Copying and pasting was unavoidable, I just wasn't sure whether to do it the painful way and just copy-paste the code a lot of times and just edit small parts of each of the components or somehow make a more efficient loop which would automate the process of what I did there... by probably using arrays. It came to my mind too, and I thought of a way to formulate the loop and the array, but I couldn't come up with any structure that could, when all combined, produce what I actually have.

If cut-pasting the code doesn't really solve the problem, we can try "zipping" the code to much smaller one by making the arrays and loops.

"When the compiler tells you that some control paths don't return a value, this means that under some circumstances (maybe that you haven't encountered in your tests yet) the code will end up returning an uninitialized value, most likely wreaking havoc at the call-site."

I'm glad we are encouraging good coding practices, but the above is not entirely true.

For example, the following code will produce that same error:

int Odd(int n)
{
    if (n%2==0)
        return 0;
    else
        return 1;
}

You can fix it by changing it to this, but IMHO this is just going to confuse anyone who reads it:

int Odd(int n)
{
    if (n%2==0)
        return 0;
    else
        return 1;

    return 0;
}

Edited 2 Years Ago by dreslough

dreslough: The first function you posted doesn't produce that error on VC++ 2014. And the second can be simplified by removing the if-else statement

int Odd(int n)
{
   return (n%2!=0);
}

I realize the code can be simplified. I was just posting an example. In VS2010, a function where all branches of an if/else or switch statement return data will still throw a warning if there is no return statement AFTER the if/else or switch statement. VS bug, IMHO.

Edited 2 Years Ago by dreslough

FYI, I actually came to this thread because I'm having the same problem as the OP. And all my files are 3K lines or less, my functions are all 100 lines or less, and I have no compiler warnings.

The rest of the internet seems to agree that it's a known bug in VS2010.

Yes, that would seem like a bug, or at least, very bad static analysis on the part of MSVC. I use mostly GCC or Clang, and I have never seen warnings for such code (i.e., if-else with no return afterwards, which is quite common). I'm quite surprised that MSVC (from VS2010) so incompetently produces such a bogus warning (and that's coming from someone who already has a very low opinion of MSVC compilers).

M$ must have corrected the problem in later versions of the compiler. Suggest the OP update to VC++ 2014, which does not produce that warning for the code snippet he posted.

from someone who already has a very low opinion of MSVC compilers

For general purpose software you're probably right. But for MS-Windows specific VC++ can't be beat even by MinGW.

Edited 2 Years Ago by Ancient Dragon

Anyway, I came to this thread because I had the same problem as the OP.

Took a hard look at my code and decided that VS might be choking on a big list of hard-coded strings inside 1 function (that passed in an index into the list in order to retrieve the string).

There were about 2000 strings, each less than 6 characters. I split the function into three functions, each with an array of about 660 strings, and VS stopped choking.

So, advice to OP or anyone similar is to just "use your spidey sense" to figure out what parts of your code have gotten unwieldy. I agree that compiler warnings are a great place to look, but don't waste time fixing warnings (like the one I posted) that don't make any sense.

This article has been dead for over six months. Start a new discussion instead.