PDA

View Full Version : Apparently inconsistent compiler behavior



Computer Hater
27th November 2010, 01:28
Hi,
I'm using Qt Creator to build a GUI application in C++.

Short description: I get different behavior of the application with apparently the same source code.

Longer description:

I tried to store some global data in a separate file, "data.h".
As a test, I defined a string inside a constructor in that file and wanted to set the text of a QLabel in my main window to that string. I later also added an output (both via qDebug and cout) to the constructor to see it it is called.

I noticed two things:
- The string didn't show up in the label upon modifying it in the data.h file. I had to clean the project first.
- The test output inside the constructor was never shown when running the program.

I also added a qDebug output along with setting the label's text, which was shown and was always consistent with what the label showed.

I then reproduced the relevant part of code in a small project "Test" to post here (The project is attached). But in the reduced test version I didn't need to clean the project in order for a modified text to appear in the label right away.

I went back to the main project and noticed that the inclusion of the file "data.h" was in multiples, so I reduced it to just one. Suddenly both problems were gone, even when I undid the change again ! (Except only the qDebug output worked, not the cout.)

Then I made some changes to the test project, recompiled, undid them again and recompiled again. I don't remember the exact course of action, but the result was that the apparently exact same program version of the test project once exhibited both problems (i.e. for a short time I needed to clean the project first before an updated string would show), and then went back to the way it was (i.e. just the constructor output didn't happen).

I have no idea what changes in the source code could have been responsible for the different behaviour. To the best of my memory for both projects the exact same source code version showed different behaviour. I can only assume that some other settings were changed implicitly that I'm not aware of.

Currently, the main project is working all right. Both problems are gone. But given that I have no explanation what either caused them or let them disappear, I expect something similar to happen again and would like to know what I can do about it the next time.

Is there any automatic setting that can cause something like that ?

The Test project is attached. For a quick reference, this is the source code of the data.h file:


#ifndef DATA_H
#define DATA_H

#include <QString>
#include <QDebug>
#include <iostream>
using namespace std;


class Files
{

public:

QString f1;
QString f2;
QString f3;

Files()
{
f1 = "test orr";
qDebug() << "Files constructor, " << f1;
cout << "Files constructor" << endl;
f2 = "";
f3 = "";
}


};

extern Files files;


and the data.cpp file:


#include "data.h"

Files files;


The main project only differs in that it has more elements, these being a push button and a menu bar, and that it has another UI file for a submenu that pops up from the menu (which I even deactivated, but that didn't do anything).


Can you please advise me on which part of the build engine can cause such a problem and where to read up on that ?
Thank you !

tbscope
27th November 2010, 04:54
Always look at the output of all the tools used to generate files, compile files, link files, ...
One common problem is that people think that qmake will run all the time. This is not true. If qmake thinks that it doesn't need to alter the makefile, it will not run. In some cases this is wrong.
Another problem might be that the compiler thinks that some files are not worth preprocessing anymore and it uses the existing object files. Sometimes incorrect.

How to solve these problems?
There is only one way to correctly build software and that is from scratch. Always clean the project from object files and generated files and rebuild.

In the past I made some changes to some KDE code. Before committing the changes I build the code and run the results to see if everything was correct. And everything always was correct before I committed the changes. But then, suddenly, someone complained that the code didn't even compile. How could that be? I checked it.
So, I double check it, and I compiled the code again (I didn't completely recompile though). Hmmm, strange, it does compile here. So I tell this other guy that he must have made an error somewhere.
Then another person tells me he can't build the code. I then started looking around what could be the problem. And some of the problems I experienced were that specific files did not get rebuild on my computer, but all these other people were building from scratch and on their computer those specific files did get rebuild resulting in some variables not being available anymore.

The tools we use are great, but when you build incrementally inside a folder that already contains generated objects and files, strange behavior can and will occur. Always clean the project and rebuild. If you're program is large, split it up in manageable parts.

wysota
27th November 2010, 15:33
I would say (without looking at the actual code) that you forgot to add some file to qmake's HEADERS variable so make doesn't know it should track it as a dependency. And please don't mix the compiler with the whole toolchain.

Computer Hater
28th November 2010, 16:33
@tbscope:
Well, I guess I have to read up a lot on the build process.

@wysota:
No, in both projects all the used files appear in the project file and all header files appear in the header variable. Actually, I used Qt Creator and they were added automatically.

I still wonder though why in the Test project the qDebug output inside the constructor doesn't work while it now works in the main project, whereas the cout output doesn't work in either case.

SixDegrees
28th November 2010, 16:44
Output goes to the console. In Windows, you don't get a console unless you explicitly request one in your project file, and your output has nowhere to appear. I don't recall the exact syntax - I work mainly in Unix - but this seems to be a common problem. Dig through the qmake documentation for more details.

Computer Hater
28th November 2010, 17:36
Well, the thing is that I do get output in both projects when I use qDebug later on, such as when setting up the UI. I just don't get any output in the Test project's constructor of the Files class, whereas the same constructor in the main project now does show output.
Both project files don't differ except for the number of files included, which in both cases are all the files in the project.
The project file of the test project is this:


#-------------------------------------------------
#
# Project created by QtCreator 2010-11-25T17:13:18
#
#-------------------------------------------------

QT += core gui

TARGET = Test
TEMPLATE = app


SOURCES += main.cpp\
mainwindow.cpp \
data.cpp

HEADERS += mainwindow.h \
data.h

FORMS += mainwindow.ui


Anyway, it's just an oddity for now and not a real obstacle, as it works fine in the main project.

wysota
28th November 2010, 20:35
@wysota:
No, in both projects all the used files appear in the project file and all header files appear in the header variable. Actually, I used Qt Creator and they were added automatically.
A respective file has to be referenced in the actual code for make (or actually probably gcc) to treat the referenced file as a dependency of the file containing the reference to the other file.