Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» Вопросы по программированию на C/С++

Автор: Zyava
Дата сообщения: 16.04.2007 23:33

Цитата:
Так я пишу на С++ Builder!
мож я не правильно высказал вопрос, то сори!
Мене надо знать как объявить переменную что бы она была видна из разных форм
то бишь из формы "Form2" видна переменная формы "Form1"


В одном файле обьявлешь переменную, например int i; , в другом файле пишешь extern int i; - будет переменная i общей для двух файлов.
Автор: Mrcloner
Дата сообщения: 17.04.2007 07:46
Понял все спасиб!
Автор: zx_alexis
Дата сообщения: 17.04.2007 17:14
Помогите, пожалуйста, с gcc. (юзаю djgpp2 - gcc 3.1)
Имеются сорцы простой операционки на чистых Сях, компилятся с помощью gcc-3.1 из djgpp в coff .o, потом собираются ld в ядро --> ядро работает, как надо)
Делаю апгрейд gcc до 4.1, компилю исходники - вылезают варнинги, но объекты создаются, линкуются в ядро. Ядро запускается, но ЧАСТЬ кода не работает (например, ввод с клавы).
Если нужны исходники, могу скинуть в мыло (автор пока их не выложил, и я потому тоже открывать их здесь не стану пока...)
Автор: Qraizer
Дата сообщения: 17.04.2007 19:03
Самое вероятное - сырцы написаны непереносимо с точки зрения стандарта. Новый компилятор более иначе трактует эту непереносимость. Приведи примеры варнингов.
Автор: zx_alexis
Дата сообщения: 17.04.2007 23:09
первоначальная версия:
Reading specs from c:/djgpp/lib/gcc-lib/djgpp/3.1/specs
Configured with: ../configure i586-pc-msdosdjgpp --prefix=/dev/env/DJDIR --disable-nls
Thread model: single
gcc version 3.1

переход на версию:
Using built-in specs.
Target: djgpp
Configured with: /gnu/gcc-4.10/configure djgpp --prefix=/dev/env/DJDIR --disable-nls --disable-werror --enable-languages=c,c++,fortran,objc,obj-c++,ada
Thread model: single
gcc version 4.1.0

Варнинги следующиеgcc-4.1)
gcc -Wall -W -O2 -nostdinc -fno-builtin -Iinclude -o objs/basio.o -c src/basio.c
gcc -Wall -W -O2 -nostdinc -fno-builtin -Iinclude -o objs/basirq.o -c src/basirq.c
gcc -Wall -W -O2 -nostdinc -fno-builtin -Iinclude -o objs/cons.o -c src/cons.c
src/cons.c: In function 'k_printf':
src/cons.c:104: warning: pointer targets in initialization differ in signedness
src/cons.c: In function 'Read_Ln':
src/cons.c:304: warning: pointer targets in assignment differ in signedness
src/cons.c: In function '_rl':
src/cons.c:320: warning: pointer targets in assignment differ in signedness
gcc -Wall -W -O2 -nostdinc -fno-builtin -Iinclude -o objs/fat12.o -c src/fat12.c
src/fat12.c: In function 'dirF12':
src/fat12.c:186: warning: pointer targets in passing argument 1 of 'findF12' differ in signedness
src/fat12.c:186: warning: pointer targets in passing argument 2 of 'findF12' differ in signedness
src/fat12.c: In function 'createF12':
src/fat12.c:276: warning: pointer targets in passing argument 2 of 'copystr' differ in signedness
gcc -Wall -W -O2 -nostdinc -fno-builtin -Iinclude -o objs/fdd.o -c src/fdd.c
src/fdd.c: In function 'fdc_rw':
src/fdd.c:222: warning: pointer targets in passing argument 1 of 'copystr' differ in signedness
src/fdd.c:222: warning: pointer targets in passing argument 2 of 'copystr' differ in signedness
src/fdd.c:296: warning: pointer targets in passing argument 1 of 'copystr' differ in signedness
src/fdd.c:296: warning: pointer targets in passing argument 2 of 'copystr' differ in signedness
gcc -Wall -W -O2 -nostdinc -fno-builtin -Iinclude -o objs/fman.o -c src/fman.c
gcc -Wall -W -O2 -nostdinc -fno-builtin -Iinclude -o objs/fs.o -c src/fs.c
src/fs.c: In function 'fopen':
src/fs.c:104: warning: pointer targets in passing argument 1 of 'copystr' differ in signedness
src/fs.c:110: warning: pointer targets in passing argument 1 of 'getdn' differ in signedness
src/fs.c:141: warning: pointer targets in passing argument 2 of 'fsys[fs].findf' differ in signedness
src/fs.c: In function 'freadb2':
src/fs.c:197: warning: dereferencing type-punned pointer will break strict-aliasing rules
src/fs.c:198: warning: dereferencing type-punned pointer will break strict-aliasing rules
src/fs.c: In function 'readdir':
src/fs.c:249: warning: pointer targets in passing argument 1 of 'getdn' differ in signedness
src/fs.c: In function 'readdir2':
src/fs.c:282: warning: dereferencing type-punned pointer will break strict-aliasing rules
src/fs.c: In function 'fwriteb2':
src/fs.c:293: warning: dereferencing type-punned pointer will break strict-aliasing rules
src/fs.c:294: warning: dereferencing type-punned pointer will break strict-aliasing rules
src/fs.c: In function 'fsize2':
src/fs.c:301: warning: dereferencing type-punned pointer will break strict-aliasing rules
gcc -Wall -W -O2 -nostdinc -fno-builtin -Iinclude -o objs/hshell.o -c src/hshell.c
src/hshell.c: In function 'printtaskinfo':
src/hshell.c:47: warning: pointer targets in passing argument 1 of 'k_printf' differ in signedness
gcc -Wall -W -O2 -nostdinc -fno-builtin -Iinclude -o objs/kernel.o -c src/kernel.c
src/kernel.c: In function 'getkey2':
src/kernel.c:722: warning: dereferencing type-punned pointer will break strict-aliasing rules
src/kernel.c: In function 'etext':
src/kernel.c:730: warning: dereferencing type-punned pointer will break strict-aliasing rules
src/kernel.c: In function '__rl':
src/kernel.c:805: warning: dereferencing type-punned pointer will break strict-aliasing rules
src/kernel.c: In function 'initdescr':
src/kernel.c:926: warning: pointer targets in passing argument 1 of 'copystr' differ in signedness
src/kernel.c: In function 'loadmodule':
src/kernel.c:943: warning: pointer targets in passing argument 1 of 'fopen' differ in signedness
src/kernel.c: In function 'mountmodfunc':
src/kernel.c:1003: warning: pointer targets in passing argument 1 of 'compareStr' differ in signedness
src/kernel.c:1003: warning: pointer targets in passing argument 2 of 'compareStr' differ in signedness
src/kernel.c: In function 'loadconf':
src/kernel.c:1030: warning: pointer targets in passing argument 1 of 'copystr' differ in signedness
src/kernel.c:1030: warning: pointer targets in passing argument 2 of 'copystr' differ in signedness
src/kernel.c:1034: warning: pointer targets in passing argument 2 of 'freadb' differ in signedness
src/kernel.c:1042: warning: pointer targets in passing argument 1 of 'copystr' differ in signedness
src/kernel.c:1042: warning: pointer targets in passing argument 2 of 'copystr' differ in signedness
src/kernel.c:1052: warning: pointer targets in passing argument 1 of 'copystr' differ in signedness
src/kernel.c:1052: warning: pointer targets in passing argument 2 of 'copystr' differ in signedness
gcc -Wall -W -O2 -nostdinc -fno-builtin -Iinclude -o objs/main.o -c src/main.c
src/main.c: In function 'main':
src/main.c:66: warning: pointer targets in passing argument 1 of 'loadmodule' differ in signedness
src/main.c:67: warning: pointer targets in passing argument 2 of 'mountmodfunc' differ in signedness
src/main.c:68: warning: pointer targets in passing argument 2 of 'mountmodfunc' differ in signedness
src/main.c:87: warning: pointer targets in passing argument 1 of 'loadmodule' differ in signedness
src/main.c:88: warning: pointer targets in passing argument 2 of 'mountmodfunc' differ in signedness
src/main.c:168: warning: pointer targets in passing argument 1 of 'thmc' differ in signedness
gcc -Wall -W -O2 -nostdinc -fno-builtin -Iinclude -o objs/math.o -c src/math.c
gcc -Wall -W -O2 -nostdinc -fno-builtin -Iinclude -o objs/mem.o -c src/mem.c
gcc -Wall -W -O2 -nostdinc -fno-builtin -Iinclude -o objs/pci.o -c src/pci.c
gcc -Wall -W -O2 -nostdinc -fno-builtin -Iinclude -o objs/strings.o -c src/strings.c
nasm -f coff -dUNDERBARS=1 -iinclude/ -o objs/kstart.obj src/kstart.asm
ld -T scripts/krnl1m.ld -nostdlib -o dist/harius objs/kstart.obj objs/basio.o objs/basirq.o objs/cons.o objs/fat12.o objs/fdd.o objs/fman.o objs/fs.o objs/hshell.o objs/kernel.o objs/main.o objs/math.o objs/mem.o objs/pci.o objs/strings.o
strip dist/harius

При компиляции на gcc-3.1 с опцией -pedantic (на соответствие ANSI-C):
gcc -Wall -W -O2 -nostdinc -fno-builtin -Iinclude -pedantic -o objs/basio.o -c src/basio.c
gcc -Wall -W -O2 -nostdinc -fno-builtin -Iinclude -pedantic -o objs/basirq.o -c src/basirq.c
gcc -Wall -W -O2 -nostdinc -fno-builtin -Iinclude -pedantic -o objs/cons.o -c src/cons.c
src/cons.c: In function `k_printf':
src/cons.c:104: warning: pointer targets in initialization differ in signedness
src/cons.c: In function `clean_src':
src/cons.c:280: warning: ISO C89 forbids mixed declarations and code
src/cons.c: In function `Read_Ln':
src/cons.c:304: warning: pointer targets in assignment differ in signedness
src/cons.c: In function `_rl':
src/cons.c:320: warning: pointer targets in assignment differ in signedness
gcc -Wall -W -O2 -nostdinc -fno-builtin -Iinclude -pedantic -o objs/fat12.o -c src/fat12.c
src/fat12.c: In function `dirF12':
src/fat12.c:186: warning: pointer targets in passing arg 1 of `findF12' differ in signedness
src/fat12.c:186: warning: pointer targets in passing arg 2 of `findF12' differ in signedness
src/fat12.c: In function `createF12':
src/fat12.c:276: warning: pointer targets in passing arg 2 of `copystr' differ in signedness
gcc -Wall -W -O2 -nostdinc -fno-builtin -Iinclude -pedantic -o objs/fdd.o -c src/fdd.c
src/fdd.c: In function `fdc_rw':
src/fdd.c:222: warning: pointer targets in passing arg 1 of `copystr' differ in signedness
src/fdd.c:222: warning: pointer targets in passing arg 2 of `copystr' differ in signedness
src/fdd.c:242: warning: ISO C89 forbids mixed declarations and code
src/fdd.c:296: warning: pointer targets in passing arg 1 of `copystr' differ in signedness
src/fdd.c:296: warning: pointer targets in passing arg 2 of `copystr' differ in signedness
gcc -Wall -W -O2 -nostdinc -fno-builtin -Iinclude -pedantic -o objs/fman.o -c src/fman.c
gcc -Wall -W -O2 -nostdinc -fno-builtin -Iinclude -pedantic -o objs/fs.o -c src/fs.c
src/fs.c: In function `fopen':
src/fs.c:104: warning: pointer targets in passing arg 1 of `copystr' differ in signedness
src/fs.c:110: warning: pointer targets in passing arg 1 of `getdn' differ in signedness
src/fs.c:141: warning: pointer targets in passing arg 2 of pointer to function differ in signedness
src/fs.c: In function `readdir':
src/fs.c:249: warning: pointer targets in passing arg 1 of `getdn' differ in signedness
gcc -Wall -W -O2 -nostdinc -fno-builtin -Iinclude -pedantic -o objs/hshell.o -c src/hshell.c
src/hshell.c: In function `printtaskinfo':
src/hshell.c:47: warning: pointer targets in passing arg 1 of `k_printf' differ in signedness
gcc -Wall -W -O2 -nostdinc -fno-builtin -Iinclude -pedantic -o objs/kernel.o -c src/kernel.c
src/kernel.c: In function `switchtask':
src/kernel.c:418: warning: ISO C89 forbids mixed declarations and code
src/kernel.c: In function `newTask':
src/kernel.c:532: warning: ISO C89 forbids mixed declarations and code
src/kernel.c: In function `print_num':
src/kernel.c:576: warning: ISO C89 forbids mixed declarations and code
src/kernel.c: In function `rirq':
src/kernel.c:680: warning: ISO C89 forbids mixed declarations and code
src/kernel.c: In function `initdescr':
src/kernel.c:908: warning: ISO C89 forbids mixed declarations and code
src/kernel.c:926: warning: pointer targets in passing arg 1 of `copystr' differ in signedness
src/kernel.c: In function `loadmodule':
src/kernel.c:943: warning: pointer targets in passing arg 1 of `fopen' differ in signedness
src/kernel.c: In function `mountmodfunc':
src/kernel.c:1003: warning: pointer targets in passing arg 1 of `compareStr' differ in signedness
src/kernel.c:1003: warning: pointer targets in passing arg 2 of `compareStr' differ in signedness
src/kernel.c: In function `loadconf':
src/kernel.c:1030: warning: pointer targets in passing arg 1 of `copystr' differ in signedness
src/kernel.c:1030: warning: pointer targets in passing arg 2 of `copystr' differ in signedness
src/kernel.c:1034: warning: pointer targets in passing arg 2 of `freadb' differ in signedness
src/kernel.c:1042: warning: pointer targets in passing arg 1 of `copystr' differ in signedness
src/kernel.c:1042: warning: pointer targets in passing arg 2 of `copystr' differ in signedness
src/kernel.c:1052: warning: pointer targets in passing arg 1 of `copystr' differ in signedness
src/kernel.c:1052: warning: pointer targets in passing arg 2 of `copystr' differ in signedness
gcc -Wall -W -O2 -nostdinc -fno-builtin -Iinclude -pedantic -o objs/main.o -c src/main.c
src/main.c: In function `main':
src/main.c:66: warning: pointer targets in passing arg 1 of `loadmodule' differ in signedness
src/main.c:67: warning: pointer targets in passing arg 2 of `mountmodfunc' differ in signedness
src/main.c:67: warning: ISO C forbids assignment between function pointer and `void *'
src/main.c:68: warning: pointer targets in passing arg 2 of `mountmodfunc' differ in signedness
src/main.c:68: warning: ISO C forbids assignment between function pointer and `void *'
src/main.c:87: warning: pointer targets in passing arg 1 of `loadmodule' differ in signedness
src/main.c:88: warning: pointer targets in passing arg 2 of `mountmodfunc' differ in signedness
src/main.c:88: warning: ISO C forbids assignment between function pointer and `void *'
src/main.c:168: warning: pointer targets in passing arg 1 of pointer to function differ in signedness
gcc -Wall -W -O2 -nostdinc -fno-builtin -Iinclude -pedantic -o objs/math.o -c src/math.c
gcc -Wall -W -O2 -nostdinc -fno-builtin -Iinclude -pedantic -o objs/mem.o -c src/mem.c
gcc -Wall -W -O2 -nostdinc -fno-builtin -Iinclude -pedantic -o objs/pci.o -c src/pci.c
gcc -Wall -W -O2 -nostdinc -fno-builtin -Iinclude -pedantic -o objs/strings.o -c src/strings.c
nasm -f coff -dUNDERBARS=1 -iinclude/ -o objs/kstart.obj src/kstart.asm
ld -T scripts/krnl1m.ld -nostdlib -o dist/harius objs/kstart.obj objs/basio.o objs/basirq.o objs/cons.o objs/fat12.o objs/fdd.o objs/fman.o objs/fs.o objs/hshell.o objs/kernel.o objs/main.o objs/math.o objs/mem.o objs/pci.o objs/strings.o
strip dist/harius
Автор: Qraizer
Дата сообщения: 18.04.2007 15:44
Так что, GNUсные спецы в отпуске?
pointer targets in passing arg 1 of `copystr' differ in signedness - смешение знаковых и беззнаковых данных; скорее всего некритично, однако while (--i < 0), например, чувствителен к подобному смешиванию.
ISO C forbids assignment between function pointer and `void *' - солидарен с компилятором. Таким кастованием полностью уничтожается (или берётся из ниоткуда) информация о параметрах и возвращаемом типе. Компилятор будет вынужден доверять программисту, тогда как обычно наоборот - программист полагается на проверки, выполняемые компилятором.
ISO C89 forbids mixed declarations and code и dereferencing type-punned pointer will break strict-aliasing rules - честно говоря, даже не понял, что за код сподвигнул компилятор на такие предупреждения... По первому варнингу, скорее всего, имеется ввиду, что, в отличие от C++, в plain-C объявления разрешается размещать только в начале функций до первой инструкции, компилируемой в исполняемый код, или же вне функций. Второй вообще не понял, к чему это.
Количество предупреждений говорит о неряшливости автора. Конкретнее, чем здесь, я заочно вряд ли смогу сказать больше.
Автор: WiseAlex
Дата сообщения: 18.04.2007 16:03
zx_alexis

Цитата:
Делаю апгрейд gcc до 4.1

сам не пробовал но в сети много отрицательных отзывов о 4,1 - может стоит пока остаться на прежней версии?
Автор: zx_alexis
Дата сообщения: 19.04.2007 00:32
пока останусь на 3.1, но готовить код и добивать его до стандарта стоит -> у меня FreeBSD с gcc3.4 - и этот код она уже не переваривает... Кстати, еще вопросик) Если я захочу собрать ядро не из coff-объектов, а на BSD-системе - реально ли это вообще, и как поменять скрипт линковщика (так как, IMHО, в нем все и заключается).
Про ключик nasm -f elf я не забуду)
Автор: slava 1
Дата сообщения: 19.04.2007 19:38
Не могу нигде найти название функции, которая могла бы выдать названия всех файлов, находящихся в папке. Или может есть какая-то другая возможность получить список.
Автор: WiseAlex
Дата сообщения: 19.04.2007 20:20
slava 1
boost::filesystem ?
Автор: xdude
Дата сообщения: 20.04.2007 10:32
Привет, народ.
Есть проблема:

Код:
volatile std::vector<std::string> data;
std::string str("Hello");
data.push_back(str);
Автор: veronica b
Дата сообщения: 20.04.2007 14:53
xdude, переменная типа volatile в языке Си, это та переменная, которая не кэшируется на регистрах процессора. Эта переменная может в любой момент изменится и поэтому, при её использовании надо обращаться в память. Что может менять вектор, состаящий из строк? Компилятор это тоже не знает!
Автор: Qraizer
Дата сообщения: 20.04.2007 15:30
Вектор объявлен с модификатором. Его метод push_back() не имеет такого модификатора. Потому и ошибка компиляции - компилятор не нашёл std::vector<>::push_back(std::vector<>::value_type) volatile.
Любой класс, который позволяет создавть свои volatile-экземпляры, должен предусмотреть соответствующие перегруженные методы. То же относится к const. Почему их нет у вектора, не знаю. Наверное потому, что такой вектор будет крайне неэффективен. Скажи лучше, зачем он тебе понадобился?
Автор: RedLord
Дата сообщения: 20.04.2007 15:32
xdude
здесь обсуждалось:
__http://groups.google.bs/group/comp.lang.c++.moderated/browse_thread/thread/bc0f4e7d86647c05/0504099fbb7e81be?lnk=gst&q=volatile&rnum=7#0504099fbb7e81be
Автор: xdude
Дата сообщения: 20.04.2007 22:44

Цитата:
Скажи лучше, зачем он тебе понадобился?

Понадгобился именно затем, зачем имеется в наличии модификатор volatile: этот вектор может в любой момент времени измениться каким-либо тредом (т.е., либо дополниться. либо уменьшиться). На самом деле, я бы пометил как volatile не весь вектор, а только его мемберскую переменную size (или что там говорит о его размере), если бы была такая возможность. Я так понял, нужно просто создать какую-то функцию, помеченную как volatile, которая просто будет возвращать размер этого вектора, но так как она будет помечена волатилом, она оптимизироваться не будет, и всё будет работать именно так, как мне нужно. Или я не прав, и всё надо сделать как-то по-другому?
Автор: slonpts
Дата сообщения: 20.04.2007 23:40
xdude
Как я понял, в твоей программе работают несколько потоков, их которых по крайней мере один пишет что-то в вектор, а другие читают.

Для корректной работы тебе придется использовать синхронизацию потоков с помошью функций, предоставляемых операционной системой (например, используя мьютексы).

В любом другом случае программа может в некоторых случаях не работать, и такие ошибки будет очень трудно отловить, т.к. их практически невозможно воспроизвести. Если тебя устраивает "теория вероятностей" - т.е. то, что программа 1 раз из 1000 может выдавать ошибку (или, что еще хуже, неправильные данные, никак не сообщая об ошибке), то можно обойтись без синхронизации потоков.

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

Если хочешь серьезно заняться синхронизацией - читай "Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows" Джеффри Рихтера.
Автор: xdude
Дата сообщения: 21.04.2007 00:22
slonpts

Цитата:
Для корректной работы тебе придется использовать синхронизацию потоков с помошью функций, предоставляемых операционной системой (например, используя мьютексы).

Не нужно путать теплое с мягким: синхронизация и оптимизация это немногот разные вещи. Синхронизацию я и без того использую. У меня есть тред, который ждет изменения этого вектора в некотором цикле и время от времени его проверяет. Сам цикл очеь которткий: проверка длины вектора и слип на несколько секунд. Естественно, изменения вектора в самом этом цикле не происходит, и оптимизатор решает, что каждый раз вытаскивать длину вектора из памяти неэффективно, и поэтому один раз помещает эту переменную в регистр перед входом в цикл, и дальше, естественно, зависает в бесконечном ожидании того, чего случиться никогда не может, так как регистр этот в данном контексте выполнения никем и никогда не поменяется. А вот если бы я пометил вектор как volatile - это сказало бы оптимизатору, что оптимизировать таким образом не стоит, так как вектор (его длина, в частности) в любой момент времени может быть изменен другим тредом или процессом, и тогда он бы проверял не закешированное в регистре значение, а в каждый проход цикла заново вытаскивал бы это значение из памяти (стэка или хипа, неважно). Модификатор volatile именно для таких случаев и придуман, так что RTFM.
Автор: vsDev
Дата сообщения: 21.04.2007 00:27
Есть такая задача: задано имя двоичного файла; заменить в этом файле все вхождения заданной последвательностти символов на некоторую другую последовательность. Например, заменить в некотором файле строки вида xxx "yyy" символами пробела. Т.е. был файл с содержимым "asdf xxx "yyyy" cfgfdgf xxx "yyy" drfsdf4remh'fdgf" - на выходе должен быть файл вида "asdf cfgfdgf drfsdf4remh'fdgf".
Просьба не писать полный код программы, а высказать мнения как лучше реализовать такую задачу (какие использовать технологии и подход). Интересует самое оптимальное по скорости решение.
Заранее спасибо.

Добавлено:
Причем значение текста yyy может быть произвольным, т.е. поиск можно осуществлять только по строке xxx " (yyy не известно до первого поиска)
Автор: RedLord
Дата сообщения: 21.04.2007 11:32
xdude
посмотри в сторону Intel Threading Building Blocks
там есть вектора, правильно работающие в нескольких потоках

P.S. судя по исходному коду, мемберы вектора (не функции) объявлены как volatile, что подавляет оптимизацию
похоже, это то, что надо
Автор: xdude
Дата сообщения: 21.04.2007 11:58
RedLord

Цитата:
посмотри в сторону Intel Threading Building Blocks

Она платная Бесплатно можно тоько для некомеческого использования.
Но всё равно спасибо
Автор: RedLord
Дата сообщения: 21.04.2007 14:18
xdude
конечно для коммерческого ПО это не подойдет. но посмотреть реализацию можно.

там шаблоны. думаю вполне реально рипнуть код
Автор: Qraizer
Дата сообщения: 21.04.2007 18:25
xdude
Цитата:
...Синхронизацию я и без того использую. У меня есть тред, который ждет изменения этого вектора в некотором цикле и время от времени его проверяет. Сам цикл очеь которткий: проверка длины вектора и слип на несколько секунд.
Не совсем правильно используешь, значит. Попробуй добавить критическую секцию к std::vector<>size(). Впрочем, читай дальше.
Цитата:
Естественно, изменения вектора в самом этом цикле не происходит, и оптимизатор решает, что каждый раз вытаскивать длину вектора из памяти неэффективно, и поэтому один раз помещает эту переменную в регистр перед входом в цикл, и дальше, естественно, зависает в бесконечном ожидании того, чего случиться никогда не может, так как регистр этот в данном контексте выполнения никем и никогда не поменяется.
Давай угадаю - ты Билдер юзаешь. Впрочем, у предыдущих Intel C++ компиляторов тоже наблюдался подобный глюк оптимизации. Скажу сразу: оптимизатор не прав, выполняя такую оптимизацию. В стандарте чёрным по белому записано: все побочные эффекты, вызванные оптимизацией, обязаны быть нейтрализованы к моменту получения функцией управления. То же относится и к возврату из функции в точку вызова. Т.е. стандарт защищает программиста от таких агрессивных оптимизаторов, позволяя ему всегда рассматривать функции как нечто неделимое.
Цитата:
...Модификатор volatile именно для таких случаев и придуман, так что RTFM.
Это-то верно (хоть и только отчасти, но не суть), но используя volatile, ты согласаешься с неоптимизацей вектора всего и везде. Ой-ёй-ёй. Я бы сказал, что это очень плохое согласие. Попробуй напиши простой код с вектором и замерь производительность с полной оптимизацией и полным её отсутствием. Разница будет в десятки раз, уж поверь.
Теперь по сути. Вот такой код у меня
Код: #include <windows.h>
#include <process.h>
#include <conio.h>
#include <cstdlib>
#include <vector>
#include <string>
#include <sstream>
#include <iostream>

std::vector<std::string> v;
HANDLE evExit;

unsigned __stdcall thread(void*)
{
while(v.size() < 400000) Sleep(1000);

while(WaitForSingleObject(evExit, 1000) == WAIT_TIMEOUT)
std::cout << v.size() << '\t';
std::cout << std::endl;
return 0;
}

int main()
{
evExit = CreateEvent(NULL, TRUE, FALSE, NULL);

unsigned threadID;
HANDLE hThread=reinterpret_cast<HANDLE>(_beginthreadex(NULL, 0, thread, NULL, 0, &threadID));

while(!kbhit() || getch()!='\x1B')
v.push_back(static_cast<std::ostringstream&>(std::ostringstream() << rand()).str());
SetEvent(evExit);
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
CloseHandle(evExit);
}
Автор: xdude
Дата сообщения: 21.04.2007 19:15

Цитата:
Попробуй добавить критическую секцию к std::vector<>size(). Впрочем, читай дальше.

Это как? Я, вообще-то, пишу кросс-платформенное приложение, пользую boost::thread и соответственно, boost::mutex, который под виндой, насколько я понимаю, и разворачивается в критическую секцию (хотя, я могу и ошибаться). И что, критические секции оптимизатор обходит стороной?

Цитата:
В стандарте чёрным по белому записано:

Про стандарт не знал. А gcc его придерживается? У меня было подобное приложение под линухом, которое временами входило в бесконечный цикл, так как там была похожая ситуация. А когда собирал без оптимизации - всё работало нормально.

Добавлено:
Qraizer
Хмм... Очень интересная ситуация получается:

Код:
class Test
{
private:
std::vector<int> tasks;
bool finish;
void th_main()
{
while (!finish)
{
cout << "foo" << "\n";
};
cout << "BAR!!!" << "\n";
};
public:
Test(): finish(false) { };
void run()
{
boost::thread th(boost::bind(&Test::th_main, this));
for (int i = 0; i < 1000000; ++i)
{
tasks.push_back(i);
};
finish = true;
th.join();
};
};
Автор: slonpts
Дата сообщения: 21.04.2007 19:33
xdude
Можешь попробовать такой финт ушами:

Код:
std::vector<std::string> v;
volatile int notCachedVectorLength;
Автор: xdude
Дата сообщения: 21.04.2007 20:06
slonpts
Да, я после долгих мучений именно так и хотел сделать, но оставлял этот как самую крайнюю меру. Наверное, придется-таки к ней прибегнуть.
Я даже пробовал написать функцию-обертку типа вот такого:

Код:
SomeClass
{
...
vector<string> someVector;
...
vector<string>::size_type getNumItems() volatile
{
return someVector.size();
}
// или так
volatile vector<string>::size_type getNumItems() volatile
{
return someVector.size();
}

Автор: RedLord
Дата сообщения: 21.04.2007 22:13
Qraizer

Цитата:
В стандарте чёрным по белому записано: все побочные эффекты, вызванные оптимизацией, обязаны быть нейтрализованы к моменту получения функцией управления


можно подробнее.

т.е. компилятор при таком коде


Код:

void test()
{
std::vector<int> v;
for (size_t i = 0; i < v.size(); i++)
{
}

// здесь код не использующий v


for (size_t i = 0; i < v.size(); i++)
{
}

}
Автор: vsDev
Дата сообщения: 22.04.2007 22:18
Пытаюсь освоить работу с файлами (MS C/С++)
Нашел в мсдн такой раздельчик:
Stream I/O functions treat data as a stream of individual characters.
Low-level I/O functions invoke the operating system directly for lower-level operation than that provided by stream I/O.
Прочитал - вроде бы понял, но хотелось бы услышать мнение бывалых, о том в каких случаях какой подход следует использовать? Или лучше использовать апишные функции для работы с файлами?
Автор: xdude
Дата сообщения: 23.04.2007 10:49
vsDev
Если тебе low-level I/O не надо - то я бы порекомендовал юзать STL-ные стримы (#include <fstream>), код будет более наглядным и более портабельным, ну и они проще в использовании.
Low-Level и API-функции обычно используют, когда нужна высокопроизводительная (и/или маловесная) программа, заточенная под конкретную ОС, ну или если не хватает функциональности более универсальных, но более ограниченных стримов.

Добавлено:
Товарисчи! Всё-таки вернусь к своему вопросу, заданному здесь
Вразумитеольного ответа, как это заставить работать, я так и не получил. Почему это не работает - я и сам знаю, меня интересует, можно ли в принципе как-то использовать бустовские байнды с обычными C-style коллбэками?
Автор: Qraizer
Дата сообщения: 23.04.2007 15:38
RedLord
Не может. const size_t sz = v.size(); // добавляется оптимизатором неправомерно, ибо вызов функции есть вызов функции, и нет никаких гарантий, что в разные вызовы она будет возвращать одинаковые результаты, что в действительности и происходит. И тот факт, что этот метод простенький и легко встраивается (в результате чего вызова метода как такового уже и нет, а вместо него оптимизатор видит его тело) ничего не меняет - стандарт об этом чётко заявляет. Глюк оптимизации как раз и проявляется в тех случаях, когда после встраивания inline-методов и функций оптимизатор "забывает" о том, что раньше это были вызовы. Другое дело, если метод имеет модификатор const и вызывается с константным экземпляром... Тогда оптимизатор имеет право оптимизировать этот вызов. И если программист его "обманул" каким-нибудь const_cast<>-ом, то виноват будет уже он.
Цитата:
можно подробнее.
Можно. Раздел 5.2.2 "Function call" пункт 8: "The order of evaluation of arguments is unspecified. All side effects of argument expression evaluations take effect before the function is entered. The order of evaluation of the postfix expression and the argument expression list is unspecified." Это что касается вызова функции. Непосредственно к рассматриваемой теме это отношения не имеет, но мною было упомянуто. Раздел 1.9 "Program execution" пункт 17: "When calling a function (whether or not the function is inline), there is a sequence point after the evaluation of all function arguments (if any) which takes place before execution of any expressions or statements in the function body. There is also a sequence point after the copying of a returned value and before the execution of any expressions outside the function11)." И сноска 11): "The sequence point at the function return is not explicitly specified in ISO C, and can be considered redundant with sequence points at full expressions, but the extra clarity is important in C++. In C++, there are more ways in which a called function can terminate its execution, such as the throw of an exception." Надо ещё отметить, что компилятор должен просечь разные области видимости у элемента вектора, в котором хранится его размер (если это и правда отдельное поле в классе) и у переменной, которой присваивается результат вызова этого метода. Он ну никак не может гарантировать полное отслеживание всего контекста использования этого экземпляра класса, за исключением весьма специальных случаев, когда этот экземпляр живёт очень недолго.
Автор: RedLord
Дата сообщения: 23.04.2007 16:17
Qraizer
Спасибо


Цитата:
Другое дело, если метод имеет модификатор const и вызывается с константным экземпляром...


а если есть mutable-мемберы? похоже и для const объектов (с mutable) поведение не должно отличаться

Страницы: 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193

Предыдущая тема: не знаю как назвать тему :-)


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.