Программирование >>  Арифметические и логические операции 

1 ... 34 35 36 [ 37 ] 38 39 40 ... 53


*this;

int main()

C1 c1, c2; c1 = c2;

Некоторые считают, что здесь должен быть вызван дефолтный оператор присваивания C1::operator=(C1&) (а не C1::operator=(C0&)), который, собственно, уже вызовет C0::operator=(C0&).

Понадобилось написать метод объекта на ассемблере, а Ватком строит имена так, что это невозможно - стоит знак : в середине метки, типа xcvvxx:svvsvv. Какие ключи нужны чтобы он такого не делал?

class A;

extern C int ClassMetod Call2Asm (A*, ...); class A

int Call2Asm(...) return ClassMetod Call2Asm(this, ...);

Сожрет любой Cpp компилятор. Для методов, которые вы хотите вызывать из asm - аналогично...

Так можно произвольно менять генерацию имён в Watcom:

#pragma aux var * ;

И var будет всегда генериться как var. А ещё лучше в данном случае использовать extern C и для переменных также.

После имени функции говорит о том, что Вaтком использует передачу параметров в регистрах. От этого помогает cdecl перед именем функции.

Пример:

extern C int cdecl my func();

Скажите почему возникает stack overflow и как с ним бороться?

Причины:

1. Велика вложенность функций

2. Слишком много локальных переменных (или большие локальные массивы);

3. Велика глубина рекурсии (например, по ошибке рекурсия бесконечна)

4. Используется call-back от какого-то драйвера (например, мыши);

В пунктах с 1 по 3 - проверить на наличие ошибок, по возможности сделать массивы статическими или динамическими вместо локальных, увеличить стек через stklen (для C++), проверять оставшийся стек самостоятельно путем сравнения stklen с регистром SP.

В пункте 4 - в функции, использующей call-back, не проверять стек; в связи с тем, что он может быть очень мал - организовать свой.

Любители Ваткома! А что, у него встроенного ассемблера нет что ли? Конструкции типа asm не проходят?

Встроенного asma у него на самом деле нет. Есть правда возможность писать asm-функции через #pragma aux

Например:

#pragma aux DWordsMover = \

mov esi, eax , \

mov edi, ebx , \

jcxz @@skipDwordsMover , \

rep movsd , \

@@skipDWordsMover: , \

parm [ebx] [eax] [ecx] modify [esi edi ecx]

void DWordsMover (void* dst, void* src, size t sz);

При создании 16-bit OS/2 executable Watcom требует либу DOSCALLS.LIB. Причем ее нет ни в поставке Ваткома ни в OS/2. Что это за либа и где ее можно достать?

Называют ее теперь по другому. В каталоге LIB286 и LIB386 есть такая OS2286.LIB. Это то, что вам нужно. Назовите ее DOSCALLS.LIB и

все.

BC не хочет понимать метки в ассемблерной вставке - компилятор сказал, что не определена эта самая метка. Пришлось определить метку за пределами ASM-блока. Может быть есть более корректное решение?

Загляните в исходники RTL от C++ 3.1 и увидите там нечто красивое. Например:

#define I asm

........

I or si,si

I ]z m1

I mov dx,1 m1:

I int 21h

и т.д.



Есть - компилировать с ключом -B (via Tasm) aka #pragma inline.

Правда, при этом могут возникнуть другие проблемы: если присутствуют имена read и read (например), то компилятор в них запутается.

Было замечено, что Борланд (3.1, например) иногда генерит разный код в зависимости от ключа -B.

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

Почему при выходе из программы под BC++ 3.1 выскакивает Null pointer assignment ?

Это вы попытались что-то записать по нулевому адресу памяти, чего делать нельзя.

Типичные причины:

♦ используете указатель, не инициализировав его. Например:

char *string; gets(string);

♦ запрашиваете указатель у функции, она вам возвращает NULL в качестве ошибки, а вы этого не проверяете.

Например:

FILE *f = fopen( gluck , w ); putcCX, f);

Это сообщение выдаётся только в моделях памяти Tiny, Small, Medium.

Механизм его возникновения такой: в сегменте данных по нулевому адресу записан борландовский копирайт и его контрольная сумма. После выхода из main контрольная сумма проверяется и если не совпала - значит напорчено по нулевому адресу (или рядом) и выдаётся сообщение.

Как отловить смотрите в HELPME!.DOC - при отладке в Watch поставить выражения:

*(char*)0,4m (char*)4

потом трассировать программу и ловить момент, когда значения изменятся.

Первое выражение - контрольная сумма, второе - проверяемая

строка.

При запуске программы из BC (Ctrl-F9) все работает нормально, а если закрыть BC, то программа не запускается. Что делать?

Если вы используете BWCC, то эту либу надо грузить самому - просто среда загружает BWCC сама и делаёт её доступной для программы. Советуем вам пользоваться таким макросом:

#define BEST EnableBWCC(TRUE); \ EnableCtl3d(TRUE); \

EnableCtl3dAutosubclass(TRUE) Потом в InitMainWindow пишете: BEST; и все будет хорошо.

Вообще-то правильнее OWLевые экзепшены ловить и выдавать сообщение самостоятельно. Заодно и понятнее будет отчего оно произошло:

int OwlMain(int /*argc*/, char* /*argv*/[]) int res;

TRY res = App().Run();

CATCH((xmsg &s)

Какие хочешь ексепшены

MessageBox(NULL, Message , s.c str());

return res;

Почему иногда пытаешься проинспектировать переменную в BC++ во время отладки, а он ругается на inactive scope?

Вот пример отлаживаемой программы. Компилим так:

bcc -v is.cpp

=== Cut ===

#include <iostream.h>

void a()

int b = 7;

cout << b << endl;

void main()

a();

=== Cut ===

Входим в TD. Нажимаем F8, оказываемся на строке с вызовом a(). Пытаемся inspect b. Естественно, не находим ничего. А теперь перемещаем курсор в окне исходника на строку с cout, но трассировкой в a() не входим и пробуем посмотреть b. И вот тут-то и получаем inactive scope.



Были у меня две структуры подобные, но вторая длиннее. Сначала в функции одна была, я на ней отлаживался, а потом поменял на вторую, да только в mallocе, где sizeof(struct ...) старое оставил, и налезали у меня данные на следующий кусок хипа

Для избегания подобной баги можно в С сымитировать Сиплюс-ный new:

#define tmalloc(type) ((type*)malloc(sizeof(type)))

#define amalloc(type, size) ((type*)malloc(sizeof(type) * (size))) Более того, в последнем define можно поставить (size) + 1, чтобы гарантированно избежать проблем с завершающим нулём в строках.

Можно сделать иначе. Поскольку присвоение от malloc() как правило делают на стилизованную переменную, то нужно прямо так и писать:

body = malloc(sizeof(*body));

Теперь вы спокойно можете менять типы не заботясь о malloc(). Ho это верно для Си, который не ругается на присвоение void* к type* (иначе пришлось бы кастить поинтер, и компилятор изменения типа просто не пережил бы).

Вообще в С нет смысла ставить преобразования от void* к указательному типу явно. Более того, этот код не переносим на C++ - в проекте стандарта C++ нет malloc() и free(), а в некоторых компиляторах их нет даже в hosted с++ заголовках.

Проще будет:

#ifdef cplusplus

# define tmalloc(type) (new type)

# define amalloc(type, size) (new type[size])

#else

# define tmalloc(type) malloc(sizeof(type))

# define amalloc(type, size) malloc(sizeof(type) * (size)) #endif

Суммируя вышеперечисленное, можно отметить следующее. Необходимо скомбинировать все варианты:

#ifdef cplusplus

# define tmalloc(type) (new type)

# define amalloc(type, size) (new type[size])

# define del(var) delete(var) #else

# define tmalloc(type) ((type*)malloc(sizeof(type)))

# define amalloc(type, size) ((type*)malloc(sizeof(type) * (size)))

# define del(var) free(var)

# define vmalloc(var)

((var) = malloc(sizeof(*(var)))) #endif

Я не понимаю, почему выдаются все файлы, вроде указал, что мне нужны только c атрибутом директория? Можно, конечно, проверять ff attrib, что нашли findfirst и findnext, но это мне кажется не выход. Может я что не дочитал или не понял?

done = findfirst( *.* , &onlydir, FA DIREC); while(!done) cout << onlydir.ff name << endl; done = findnext(&onlydir); Это не баг, это фича MS DOS. Если атрибут установлен, то находятся как файлы с установленным атрибутом, так и без него. Если не установлен, то находятся только файлы без него. И проверять ff attrib вполне выход. Вы не дочитал хелп про findfirst/findnext.

Создается файл: fopen(FPtr, w ). Как может случиться, что структура пишется на диск некорректно?

fopen (FPtr, wb );

Режим не тот...

При печати функцией cprintf в позицию экрана x = 80, y = 25 происходит автоматический перевод строки (сдвиг всего экрана на строку вверх и очистка нижней строки) и это знакоместо так и остается пустым. Может кто знает, как вывести символ в это знакоместо?

Нажмите Ctrl+F1 на слове wscroll в Борландовском IDE. Правда, printf это не вылечит, так как его вывод идёт не через борландовскую библиотеку.

Как очистить текстовый экран в стандарте ANSI C?

Никак, в ANSI C нет понятия экрана и текстового режима. В Turbo

С так:

#include <conio.h>

void main(void) clrscr();

Можно также попробовать выдавать ANSI ESC-коды или сделать следующее:

#include <stdio.h> #define NROWS 2*25 /*



1 ... 34 35 36 [ 37 ] 38 39 40 ... 53

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика