LINUX.ORG.RU

QT C++ объявление объектов

 ,


1

4

Либо я совсем дурак,либо у QT какйто свой C++

QObject *a[3];
if(a[0]){....код...}

Если объект не объявлен то [код] не выполняется,логично.

QObject *a[3];
a[0]=new QObject();
if(a[0]){....код...}

Тут [код] выполняется.

Если объявить QObject *a[3]; в заголовочном файле То if(a[0]) всегда будет true,т.е. почемуто считается что объект объявлен?

НО Если объявить в заголовочном файле QObject *a; И проверить if(a){....код...} Будет ВЕРНО(т.е. отвечать false если не объявлен) работать,ПОЧЕМУ?

Конечно есть вариант что я забыл/недоучил С++

Также добавлю-у меня пол программы щас отвалилось из-за этого,причем qt я не обновлял,обновил только gcc,и старый бинарник работает,а новый компилируется и падает. Что за магия такая?

Спасибо за помощь.



Последнее исправление: tester9999 (всего исправлений: 1)

Конечно есть вариант что я забыл/недоучил С++

nanoolinux ★★★★
()

Конечно есть вариант что я забыл/недоучил С++

А именно работа с указателями и создание объектов.

Chaser_Andrey ★★★★★
()

Либо я совсем дурак,либо у QT какйто свой C++

Первое.

QObject *a[3] непроинициализирован и там мусор, отличный от нуля

staseg ★★★★★
()
Ответ на: комментарий от tester9999

Что такое QObject *a[3] и что оно в себе содержит, ты можешь сказать?

Chaser_Andrey ★★★★★
()
Ответ на: комментарий от tester9999

Спасибо, ты сделал мой час.

anonymous
()

Спасибо за конструктивные ответы.

Хоть один сможет объяснить почему на clang работает на gcc нет?

tester9999
() автор топика

Либо я совсем дурак,либо у QT какйто свой C++

Это у вас какой-то свой C++. Инициализируйте массив нулями и будет все ок.

обновил только gcc

Работа вашей программы зависит от фаз луны.

no-such-file ★★★★★
()
// $ ./a.out 
a[0] = 0x7f7196e09c48 1
b[0] = 0 0
a[1] = 0x400c40 1
b[1] = 0 0
a[2] = 0 0
b[2] = 0 0
// $ cat test.cpp 
#include <iostream>

int main() {
    int *a[3];
    int *b[] = {0, 0, 0};

    for (int i = 0; i < 3; i++) {
        std::cout << "a[" << i << "] = " << a[i] << " " << bool(a[i]) << std::endl;
        std::cout << "b[" << i << "] = " << b[i] << " " << bool(b[i]) << std::endl;
    }
}
anonymous
()
if(a[0] != NULL) {
...

же.

В заголовочном файле обявлять без extern в cpp не стоит. Да и вообще глобальные переменные не нужны. Пользуйся классами, читай книжки дальше (про шаблоны проектирования тоже почитай).

И уж если Qt, то уж QVector.

unfo ★★★★★
()
Ответ на: комментарий от unfo

if(a[0] != NULL) {

Ну это конечно все меняет. (btw, в C++11 свой nullptr)

anonymous
()
Ответ на: комментарий от tester9999

Счастливчик. Повезло, что сразу не работает, могло бы и стрельнуть, лет через несколько, на Марсе. Завидую.

ilovewindows ★★★★★
()
Ответ на: комментарий от anonymous

Еще раз для тебя:

Если в коде(в самом cpp файле) объявлять QObject *a[3]; то все работает,и элементы необъявлены.

Если объявить QObject *a[3]; в заголовочном файле-неработает,но работает в старом gcc и clang.

Если объявлять объект QObject *a; работает везде.

Объяснишь?

tester9999
() автор топика
Ответ на: комментарий от no-such-file

Работа вашей программы зависит от фаз луны.

вот ненадо.

Работа программы вполне четко зависит от компилятора,т.е. старые бинарники работают уже около полугода без проблем,и работают однозначно.

С новым gcc не запускаются потомучто считается что объекты существуют если объявлены в заголовочном файле.

Ситуация четкая и однозначная.

tester9999
() автор топика
Ответ на: комментарий от tester9999

Вообще, толсто, но было весело.

anonymous
()

сударь, вы упороты! вам всей толпой обьязняют что при обьявлении ваш масив не инициализируется нулями, а рандомным мусором, который по стечению обстоятельств может быть 0. Так что таки да работа вашей програмы зависит от расстановки звёзд и всемирно баланса добра.

Stvad
()
Ответ на: комментарий от Stvad

Я выше уже ответил что это не так,и зависит это от компилятора-и точнее gcc.

при обьявлении ваш масив не инициализируется нулями

Это вполне очевидно,но только инициализировать как NULL тоже нельзя,и угадай почему-потому что компилятор msvc будет давать странные результаты на выходе,также с callback функциями winapi будут баги из за этого.

tester9999
() автор топика
Ответ на: комментарий от tester9999

Я просто хуею. Если нулями инициализировать нельзя, тогда зачем ты вообще сравниваешь эти указатели с нулем? Или компилятору можно, а программисту - нет?

staseg ★★★★★
()
Ответ на: комментарий от tester9999

Зависит от версии gcc.

Ты еще попробуй сравнить отладочную и релизную сборки, удивишься.

m0rph ★★★★★
()
Ответ на: комментарий от anonymous

gcc 4.5 работало(точнее нескажу той системы уже нет под руками)

Текущая 4.6 неработает

Текущий clang-работает(подозреваю все всех версиях будет работать)

msvc 2010/2008 работает и там и там.

tester9999
() автор топика
Ответ на: комментарий от tester9999

tester9999

Это вполне очевидно,но только инициализировать как NULL тоже нельзя,и угадай почему-потому что компилятор msvc будет давать странные результаты на выходе,также с callback функциями winapi будут баги из за этого.

А если инициализировать рандомными числами, то всё чики-пуки?

unC0Rr ★★★★★
()
Ответ на: комментарий от tester9999

В C++ объявленный объект не обязан сам собой инициализироваться. И обычно компиляторы его инициализирую только в debug конфигурации. Сомневаюсь, что вы хотя бы с -O2 компилировали.

В конце концов, когда нибудь придётся выделять память через new - и тогда нежелание инициализировать переменные дорого станет.

quiet_readonly ★★★★
()
Ответ на: комментарий от tester9999

компилятор msvc будет давать странные результаты на выходе,также с callback функциями winapi будут баги из за этого.

Т.е. кругом чудеса и волшебство, сути которых ты не понимаешь, зато уверен, что все проблемы из-за номера версии gcc?

m0rph ★★★★★
()
Ответ на: комментарий от tester9999

вот ненадо.

Работа программы вполне четко зависит от компилятора

Возмем таракана, поставим его на пол и хлопнем в ладоши. таракан побежит.

Возьмем этого таракана снова и оторвем ему ноги. Хлопнем в ладоши. Таракан не побежит.

Вывод - орган слуха находится у таракана в ногах!

Ситуация четкая и однозначная!!11

no-such-file ★★★★★
()

Т.е. никто незнает почему так,забавно.

Факты:

На 4.6 gcc дает всегда true-работает неправильно(по моему естественно)

На 4.5(может и ниже версии) работает правильно.

На msvc-работает верно.

На clang-работает верно.

tester9999
() автор топика
Ответ на: комментарий от tester9999

Тебе уже сколько раз сказали, что по стандарту там мусор?

panter_dsd ★★★★
()
Ответ на: комментарий от Stvad

Все в этом треде первокурсники не более(кроме меня естественно).

Вы понятия не имеете о работе С++ и в том что эта проблема действительно QT-спецефичная.

Для <анонимуса с кодом> QT C++ объявление объектов (комментарий)

Намекну тебе:

Скомпиляй как у меня написано выводя значения a[],и не выводя,обратись к a[] в коде один/два/больше раз-тебя удивит резулььтат(дада он будет нерандомный)

И причина тут совсем не в мусоре.Думайте дальше.

tester9999
() автор топика
Ответ на: комментарий от tester9999

Что за магия такая?

Никакого волшебства нет

Оно и видно. Объявления локальных переменных компилятор преобразует в код, который из stack pointer register просто вычитает размер твоих локальных переменных, таким образом резервируя под них место. Но не инициализирует его нулями. Для QObject *a[3]; на x86 получишь при входе в функцию что-то вроде

push ebp
mov ebp, esp
sub esp, 96    ; <<< вот тут происходит резервирование памяти
Когда идет обращение к первому элементу твоего массива, процессор извлекает его из зарезервированной на предыдущем этапе памяти, где у тебя находится случайный мусор (никто же не записывал туда нули), оставшийся после работы предыдущего кода. Таким образом гарантии, что там находится 0 у тебя нет. При отладочной сборке правда компилятор часто инициализирует все локалки нулями, поэтому получается то, что ты хочешь. Но такое поведение реализуется разработчиками компиляторов по своему усмотрению. Тебе уже 100500 раз все объяснили в этой теме, если не хочешь прислушиваться, зачем тогда вообще задавал вопрос?

Конечно есть вариант что я забыл/недоучил С++

У меня для тебя плохие новости..

m0rph ★★★★★
()
Ответ на: комментарий от m0rph

гарантии, что там находится 0 у тебя нет

Ты неповеришь...

Иди потесть на силанге и разных версиях gcc(без debug),ну и на msvc для общего развития.

Компилятор дает однозначный код всегда,рандома там нет,и нули у всех элементов массива могут быть при определенных условиях(и версии компилятора естетсвенно).

tester9999
() автор топика
Ответ на: комментарий от tester9999

Скомпиляй как у меня написано выводя значения a[],и не выводя,обратись к a[] в коде один/два/больше раз-тебя удивит резулььтат(дада он будет нерандомный)

О боги! Да худей уже.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.