Qt, GCC, SSE and stack alignment - qt

I'm trying to make a program compiled with GCC and using Qt and SSE intrinsics.
It seems that when one of my functions is called by Qt, the stack alignment is not preserved. Here's a short example to illustrate what I mean :
#include <cstdio>
#include <emmintrin.h>
#include <QtGui/QApplication.h>
#include <QtGui/QWidget.h>
class Widget: public QWidget {
public:
void paintEvent(QPaintEvent *) {
__m128 a;
printf("a: 0x%08x\n", ((void *) &a));
}
};
int main(int argc, char** argv)
{
QApplication application(argc, argv);
Widget w;
w.paintEvent(NULL); // Called from here, my function behaves correctly
w.show();
w.update();
// Qt will call Widget::paintEvent and my __m128 will not be
// aligned on 16 bytes as it should
application.processEvents();
return 0;
}
Here's the output:
a: 0x0023ff40 // OK, that's aligned on 16 bytes
a: 0x0023d14c // Not aligned!
Configuration:
Intel Core2
WinXP, SP3
GCC 4.4 (Mingw included in the Qt SDK 2010.01)
I tried to compile the example program with the same options as those I saw in the Qt makefile :
-O2 -Wall -frtti -fexceptions -mthreads
,link options:
-enable-stdcall-fixup -Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-reloc -Wl,-s -mthreads
Now I don't know in which directions to search.
Any hints would be appreciated. Thanks!
Fabien

You can use the option -mstackrealign to do that without adding attributes to your source code:
-mstackrealign
Realign the stack at entry. On the Intel x86, the -mstackrealign option will generate an alternate prologue and epilogue that realigns the runtime stack if necessary. This supports mixing legacy codes that keep a 4-byte aligned stack with modern codes that keep a 16-byte stack for SSE compatibility. See also the attribute force_align_arg_pointer, applicable to individual functions.
(from the GCC docs)

__attribute__((force_align_arg_pointer)) void paintEvent(QPaintEvent *);
made it work! Does anybody have a better solution?

Related

MarbleWidget with Qt5 support - example code no longer exits properly

I'm writing a marine navigation app. I am a Qt5 and Marble newbie, but this was working so well, until I hit this block.
It uses MarbleWidget as a way of displaying outputs from the application, closely modelled on an example application supplied with Marble.
When I ported this to Qt5 at recent releases (opensuse), 5.14.0, it stopped working properly - it will no longer exit the application by clicking on the x button in the top right of the title bar.
This behaviour is exhibited by the sample code supplied with Marble as well.
Here is the sample application:
#include <QtWidgets/QApplication>
#include <marble/MarbleWidget.h>
#include <marble/GeoPainter.h>
using namespace Marble;
class MyMarbleWidget : public MarbleWidget
{
public:
virtual void customPaint(GeoPainter* painter);
};
void MyMarbleWidget::customPaint(GeoPainter* painter)
{
GeoDataCoordinates home(8.4, 49.0, 0.0, GeoDataCoordinates::Degree);
painter->setPen(Qt::green);
painter->drawEllipse(home, 7, 7);
painter->setPen(Qt::black);
painter->drawText(home, "Hello Marble!");
}
int main(int argc, char** argv)
{
QApplication app(argc,argv);
MyMarbleWidget *mapWidget = new MyMarbleWidget;
mapWidget->setMapThemeId("earth/openstreetmap/openstreetmap.dgml");
mapWidget->show();
return app.exec();
}
and my Makefile is:
all: pre bld post
bld: quick_marble.x
quick_marble.x : quick_marble.cpp
g++ -g -fpic -I /usr/include/qt5/ -I/usr/include/qt5/QtWidgets \
-I/usr/include/qt5/QtGui \
-I/usr/include/qt5/QtCore \
-o quick_marble.x \
quick_marble.cpp \
-L/usr/local/lib64 -lmarblewidget-qt5 -lQt5Core -lQt5Widgets -lQt5Gui
pre :
rm -f *.x
rm -f *.list
post :
ldd quick_marble.x >quick_marble.modules.list
echo all done
I have tried some work-arounds, but nothing seems to solve this issue.
I have posted the issue in a marble forum, but it hasn't been looked at for several months.
Any ideas to move forward would be helpful.

Separate class for Qt app

Under Fedora 27 Linux I want to try out a simple Hello World example with Qt and C++. I've created a separate GUI class which is populated with a label and a button. The init macro “Q_OBJECT” was commented out, because it produces an error message. ("undefined reference to vtable for MainWindow") After compiling the sourcecode, a window is shown on the screen, but the label and the button is missing. I mean, the compilation process works, the gui starts, but the result is not as expected.
If i put all the commands in the main-function without creating a separate class, Qt works great. The problem is to define a separate class which inherits from QMainWindow. Most of the example tutorials out there are working with Qt-Creator, but i want to do it from scratch on the command line level. Any hints are welcome.
// compile: clang++ -std=c++14 -lQtCore -lQtGui file.cpp
#include <QtGui/QApplication>
#include <QtGui/QPushButton>
#include <QtGui/QTextEdit>
#include <QtGui/QLabel>
#include <QtGui/QMainWindow>
#include <iostream>
class MainWindow : public QMainWindow {
//Q_OBJECT
public:
QWidget window;
MainWindow() {
window.resize(500, 400);
QLabel label1( "input:" , &window);
QPushButton button ("run", &window);
button.move(0,300);
}
void show() {
window.show();
}
};
int main(int argc, char **argv)
{
QApplication app (argc, argv);
MainWindow mywindow;
mywindow.show();
return app.exec();
}
QLabel label1 and QPushButton button are local variables in the constructor MainWindow::MainWindow(). Hence, when constructor returns they are going out of scope and are destroyed/deleted. You have to make them member variables. (This is actually a C++ issue.)
Additionally, I recommend to learn about layouting in Qt. Qt doc. provides examples e.g. Basic Layouts Example
Here is an even smaller I composed by modifying the OP:
testQMainWindow.cc:
#include <QtWidgets>
class MainWindow: public QMainWindow {
private:
QWidget central;
QHBoxLayout hBox;
QLabel label;
QPushButton button;
public:
MainWindow();
};
MainWindow::MainWindow():
hBox(this),
label("input:", this),
button("run", this)
{
hBox.addWidget(&label, 1);
hBox.addWidget(&button, 0);
central.setLayout(&hBox);
setCentralWidget(&central);
}
int main(int argc, char **argv)
{
QApplication app(argc, argv);
MainWindow win;
win.show();
return app.exec();
}
testQMainWindow.pro:
SOURCES = testQMainWindow.cc
QT += widgets
Compile and test:
$ qmake-qt5 testQMainWindow.pro
$ make
g++ -c -fno-keep-inline-dllexport -D_GNU_SOURCE -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I. -isystem /usr/include/qt5 -isystem /usr/include/qt5/QtWidgets -isystem /usr/include/qt5/QtGui -isystem /usr/include/qt5/QtCore -I. -I/usr/lib/qt5/mkspecs/cygwin-g++ -o testQMainWindow.o testQMainWindow.cc
g++ -o testQMainWindow.exe testQMainWindow.o -lQt5Widgets -lQt5Gui -lQt5Core -lGL -lpthread
$ ./testQMainWindow
I'm working on Windows 10. I did the sample in cygwin which is the closest to Linux I have at hand.
i want to do it from scratch on the command line level
In this case you either have to take care for all the necessary additional build steps, includes and linkage yourself, as Dmitry already hinted in a comment. Or you just use qmake, which is highly recommended, because it takes care of all the Qt specific stuff.

Cannot convert objects to pointers C++

I've stayed up all night trying to figure this out (it's now 7am where I'm at...).
I'm having trouble setting the address of an instantiated object to a pointer. Here's the main function:
#include "position_vector.h"
int main(){
PositionVector res = PositionVector(10);
PositionVector * ptr;
ptr = &res; // <--- WHERE IT BREAKS
}
A stripped down version of the h file "position_vector.h":
#include<iostream>
typedef uint32_t word_t;
class PositionVector {
public:
word_t * vec;
/*some other member variables */
PositionVector();
PositionVector(size_t len);
PositionVector & operator & ();
PositionVector & operator !();
~PositionVector();
/*some other member functions*/
void resize(size_t len);
};
I have another cpp file that defines all the methods in the class.
This is part of some larger set of code but here's the compile that fails:
g++-4.9 -std=c++11 -Werror -Wall -Wextra -g -Isrc -ggdb -c -o bin/main.o src/main.cpp
It fails with the error:
g++-4.9 -std=c++11 -Werror -Wall -Wextra -g -Isrc -ggdb -c -o bin/main.o src/main.cpp
src/main.cpp: In function ‘int main()’:
src/main.cpp:27:9: error: cannot convert ‘PositionVector’ to ‘PositionVector*’ in assignment
ptr = &res;
^
I must be missing something super basic but I've just pulled an all nighter and I have to run to work... so I cant really think full well any more.
You've overloaded operator& in your class:
class PositionVector {
// ...
PositionVector & operator & ();
};
When you than try to take the address, the compiler calls your overloaded member function which returns a PositionVector&. This cannot be assigned to a PositionVector* and thus you get the error.

Emacs embedded in a Qt Application

I've tried to embed emacs in a Qt Application using QX11EmbedContainer, and works but with two important exception. First of all, here is the code:
#include <QX11EmbedWidget>
#include <QtGui>
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QX11EmbedContainer container;
container.show();
container.resize(500, 500);
QProcess* process = new QProcess(&container);
QString executable("emacsclient");
QStringList arguments;
arguments << "--parent-id" << QString::number(container.winId());
process->start(executable, arguments);
int status = app.exec();
process->close();
return status;
}
And the compilation and execution line (and the previous thrown of the emacs server):
$ emacs -q --daemon &
// filtered output
$ g++ test.cpp -lQtGui -lQtCore -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4
$ ./a.out
And finally, the result:
But, when or if I try to write something in the minibuffer, the size of the widget is collapsed, and the focus is also lost:
If I make click in the (now shorter) widget, I can continue working with emacs without problems, but I should resize the window in order to emacs is expanded other time as originally.
Where is the problem?
Try using a layout.
Here is the Qt5 documentation on layout management.

Using QApplication with command line arguments

QApplication::QApplication ( int & argc, char ** argv )
Initializes the window system and constructs an application object
with argc command line arguments in argv.
Warning: The data referred to by argc and argv must stay valid for the
entire lifetime of the QApplication object. In addition, argc must be
greater than zero and argv must contain at least one valid character
string.
From this link: http://doc.qt.io/qt-4.8/qapplication.html#QApplication
What can be the arguments to the executable file? Any examples?
I tried specifying something like:
anisha#linux-dopx:~/Desktop/notes/qt> make
g++ -c -m64 -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I../../../qtsdk-2010.05/qt/mkspecs/linux-g++-64 -I. -I../../../qtsdk-2010.05/qt/include/QtCore -I../../../qtsdk-2010.05/qt/include/QtGui -I../../../qtsdk-2010.05/qt/include -I. -I. -o widgets.o widgets.cpp
g++ -m64 -Wl,-O1 -Wl,-rpath,/home/anisha/qtsdk-2010.05/qt/lib -o qt widgets.o -L/home/anisha/qtsdk-2010.05/qt/lib -lQtGui -L/home/anisha/qtsdk-2010.05/qt/lib -L/usr/X11R6/lib64 -lQtCore -lpthread
anisha#linux-dopx:~/Desktop/notes/qt> ./qt 2 f g
anisha#linux-dopx:~/Desktop/notes/qt>
Nothing special happened, nor I knew what I was doing or what I was supposed to do.
EDIT 1: The code on which I tried the ./qt -style=windows.
#include <QtGui>
int main (int argc, char *argv[])
{
QApplication app (argc, argv);
QWidget objQWidget;
objQWidget.show ();
objQWidget.resize (320, 240);
objQWidget.setWindowTitle ("Text to be shown on the title bar\n");
// Adding a "child" widget.
QPushButton *objQPushButton = new QPushButton ("Text to be shown on the button", &objQWidget);
objQPushButton->move (100, 100);
objQPushButton->show ();
return app.exec ();
}
The arguments passed in the constructor are later accessible through the static method
QStringList QCoreApplication::arguments(). By this, command line arguments can be handled everywhere in your code.
Continue reading that documentation. The set of flags QApplication acts on is listed there.
Try for example:
./qt -style=windows
The arguments that QApplication doesn't deal with are simply left alone. The ones it does process are removed (which is why that function takes non-const arguments).
The suggestion about using QCoreApplication is only recommended of you have a console application. If you are using a QApplication instead, and want to access command-line arguments from inside a QWidget, you can do it with the global pointer qApp:
Here you can find the documentation from Nokia, or here from qt-project.org . In the documentation browser of Qt Creator I couldn't find it, so it is at best not that easily accessible.
so you can find:
int my_argc = qApp->arguments().count();
QString my_argv_0 = qApp->arguments.at(0);
...
and so on.
I know this question is old, but took me some time to find a way to do it from within my Main Window, so hope this helps someone else.
Thanks, Dissident penguin! This helped me a lot!
Just note that:
QString my_argv_0 = qApp->arguments.at(0);
should be replaced with:
QString my_argv_0 = qApp->arguments().at(0);
(note the additional () after 'arguments')

Resources