среда, 31. март 2010.

C++0x

Данас коначно узмем мало времена да прочитам о новом Ц++ стандарду:
http://en.wikipedia.org/wiki/C%2B%2B0x

Оно што ми је нарочито привукло пажњу јесте увођење кључне речи auto.

Мотивација ми је потпуно јасна, и свакако је јасна свакоме ко је користио bind шаблоне. Оно чега се бојим, међутим, је могућност коришћења auto за било који тип података.

Питам се колико ће времена проћи док се не појаве "нови" пројекти који користе auto свуда (вероватно ће личити на бејзик програм).

понедељак, 15. март 2010.

Убунту

Прошле недеље сам инсталирао Убунту 9.10 на лаптоп. Изабрао Српски језик и инсталирао. Инталација је прошла без проблема, скоро сви периферијски уређаји су били препознати "из прве" или је требало учинити два клика мишем да би прорадили.

Брзина је завидна у односу на Висту коју сам имао пре тога, али оно што ми се нарочито свиђа је то да је подршка различитим језицима урађена изненађујуће добро. Преводи на Српски су, колико могу да видим, такође прилично добри.

понедељак, 1. март 2010.

sizeof(void)

Интересантно питање које ми је данас поставио колега. Стварно, колики је sizeof(void)?

Знам да може да се користи као аргумент шаблона, па сам претпоставио да је то легалан израз. Међутим, преварио сам се у величини: претпоставио сам 0, али је стварно 1. Барем како то Гну-ов компајлер каже. У стандарду "C99", брзо тражење речи "void" није дало одговор, тако да сада нисам сигуран да ли је 1 према стандарду или је то Гну-ова имплементација.


--- 5 минута касније ---

Дакле, пажљивије читање стандарда даје одговор: ово није легалан c99 израз и ради се о нестандардној имплементацији Гну-овог компајлера. Уколико користим "-std=c99 -pedantic" компајлер пријављује упозорење.

Конкретан текст стандарда који ово јасно показује се налази у поглављу 6.5.3.4 ИСО Ц стандарда 9899:1999 где каже да оператор sizeof не може да се користи на изразе који имају тип функције или некомплетни тип, итд. Како је void некомплетан тип података, sizeof(void) није легалан израз.

среда, 3. фебруар 2010.

Проблем

Управо сам суочен са интересантним проблемом који још увек не знам да решим. Ради се о седећем:

Имам блок меморије, унутар њега елементе са заглављем и слободним простором. Уколико је задато поравнање поинтера, треба да нађем поинтер у једном од слободних простора који је поравнан на дату вредност. Другим речима, уколико имам поинтер p, и величину елемента (заглавље + слободни простор), да ли је могуће доказати да постоји такав цели број N за који ће следећа једначина да важи:

p + N * dist = M * alignment

где су
p - поинтер на први слободни простор блока
N - произвољни цели број
dist - величина елемента (заглавље + слободни простор)
M - произвољни цели број
alignment - поравнање, мора бити 2 на целобројни експонент.


----

После мало размишљања, математика би могла да буде ово:

Формулу поделим са alignment:

p / alignment + N * dist / alignment = M

Резултат дељења би могао бити:

P + Mp / alignment + N * dist / alignment = M

С обзиром да доказујем само да ли постоје такви целобројни N и M, није битно која је њихова вредност, па онда целобројну вредност P стапам са M i dobijam neki novi celobrojni broj R.

Mp / alignment + N * dist / alignment = R

Да би горња једначина била задовољена, рационални број треба да нестане, а то може само ако:

N * dist = alignment - Mp

односно

N = (alignment - Mp) / dist

Дакле уколико је остатак овог дељења 0, такви бројеви постоје:

if (mod((alignment - mod(p / alignment))/dist) == 0) -> Da
else -> NE


----
После пуно размишљања, и дискусије са Страхињом, мој закључак је да таква општа формула не постоји. На крају сам променио алгоритам за испитивање подобности датог блока и сада је овакав.

Ако су сви следећи услови испуњени, блок је подобан:

1. Све корисничке алокације унутар блока су поравнате на 2^k адресе (другим речима, првa корисничка адреса унутар блока је 2^k)
2. Тражено поравање је такође 2^k
3. Величина алокационог елемнта (кориснички простор + контролна структура) мора бити такође 2^k
4. Тражено поравање мора бити мање или једнако величини алокационог елемента.

Тако се алокација врши само ако су задовољени горе наведени услови, а све остало се одбацује и алокација се врши од општег "list allocator".

уторак, 2. фебруар 2010.

"exec" на виндовсу

Једна стара белешка:

"еxec" у мајкрософтовој "C" библиотеци не ради исто као на посикс системима. У мајкрософтовој имплементацији ова функција креира нови процес који наслеђује "handles", oтворене фајл дескрипторе и слично, али добија нови број процеса (process id).

Тако програм који "рачуна" на нормално понашање ове функције може да мисли да је процес који је креирао већ завршио иако се то није стварно догодило. На пример, грешка која се десила у пракси је да је један скрипт стартовао апликацију која је користећи "exec" требало да направи нови процес, а скипт је у међувремену чекао да се оригинални процес који је креирао заврши. Међутим, виндовс би вратио контролу скипрти тако да изгледа као да се креирани програм завршио, али у стварности нови процес са новим бројем процеса би наставио да ради.

Поправка се састојала у замени "exec" позива у поменутој апликацији са "spawn" и затим чекања новокреираног процеса из саме апликације, па тек онда изласка како би скрипт могао да настави да чека само на апликацију.

субота, 28. новембар 2009.

elif евалуација

Интересантна промена се десила у gcc Ц препроцесору. Евалуација elif гране препроцесорске директиве "if" се извршава чак и ако је услов дат у if задовољен.

Конкретан пример:

#ifdef
#ifndef FOO_BAR
#define FOO_BAR
#elif FOO_BAR == 0
#endif

Ово ради без проблема на претходним верзијама, на пример 4.3.3 али не и на 4.4.1. Не знам у којој тачно верзији је дошло до промене, али ево извештаја проблема: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36320

Исправна конструкција горе наведеног примера би била:


#ifdef
#ifndef FOO_BAR
#define FOO_BAR 1
#elif FOO_BAR == 0
#endif

петак, 27. новембар 2009.

Секвентна тачка

Односно "Sequence point".

Питање у вези секвентне тачке (ако сам превео добро) често долази на разговорима за посао. Многи нису свесни шта је то иако је у суштини проста ствар. Пре неки дан ме на то потсетио бивши колега, а и ја сам то питање добио на мом разговору.

Секвентна тачка је синтаксни елемент дефинисан језиком који гарантује да ће споредни ефекти евалуације израза са леве стране таквог елемента гарантовано бити завршени пре него што започне евалуација израза са десне стране.

На пример, у Цеу и Це++ то је оператор зарез ',' али не и аримтетички оператори. Осим зареза, има још секвентних тачака као што су '?' и логички оператори.

Кратак, али добар текст се може наћи на википедији.