Showing posts with label C++. Show all posts
Showing posts with label C++. Show all posts

Monday, April 20, 2009

ASN1C

asn1c compiler
example patch:

diff -uw libasn1compiler/asn1c_misc.c.old libasn1compiler/asn1c_misc.c
--- libasn1compiler/asn1c_misc.c.old 2009-04-20 22:56:12.000000000 +0400
+++ libasn1compiler/asn1c_misc.c 2009-04-20 22:58:47.000000000 +0400
@@ -16,7 +16,7 @@
  "enum", "union", "struct", "typedef", "class",
  "switch", "case", "default", "break", "continue",
  "if", "else", "do", "for", "while", "goto",
- "sizeof", "return"
+ "sizeof", "return", "and", "or", "not", "xor"
 };
 static int
 reserved_keyword(const char *str) {


Full patch published there

Sunday, December 7, 2008

My Ubuntu installation config variables:

Linux kubic-roman 2.6.24-22-generic #1 SMP Mon Nov 24 18:32:42 UTC 2008 i686 GNU/Linux

generated by APUE2 book chapter 2 program:

opt.txt


_POSIX_ADVISORY_INFO is defined (val is 200112)
sysconf says _POSIX_ADVISORY_INFO = 200112

_POSIX_ASYNCHRONOUS_IO is defined (val is 200112)
sysconf says _POSIX_ASYNCHRONOUS_IO = 200112

_POSIX_BARRIERS is defined (val is 200112)
sysconf says _POSIX_BARRIERS = 200112

_POSIX_CPUTIME is defined (val is 0)
sysconf says _POSIX_CPUTIME = 200112

_POSIX_CLOCK_SELECTION is defined (val is 200112)
sysconf says _POSIX_CLOCK_SELECTION = 200112

_POSIX_FSYNC is defined (val is 200112)
sysconf says _POSIX_FSYNC = 200112

_POSIX_IPV6 is defined (val is 200112)
sysconf says _POSIX_IPV6 = 200112

_POSIX_MAPPED_FILES is defined (val is 200112)
sysconf says _POSIX_MAPPED_FILES = 200112

_POSIX_MEMLOCK is defined (val is 200112)
sysconf says _POSIX_MEMLOCK = 200112

_POSIX_MEMLOCK_RANGE is defined (val is 200112)
sysconf says _POSIX_MEMLOCK_RANGE = 200112

_POSIX_MONOTONIC_CLOCK is defined (val is 0)
sysconf says _POSIX_MONOTONIC_CLOCK = 200112

_POSIX_MEMORY_PROTECTION is defined (val is 200112)
sysconf says _POSIX_MEMORY_PROTECTION = 200112

_POSIX_MESSAGE_PASSING is defined (val is 200112)
sysconf says _POSIX_MESSAGE_PASSING = 200112

_POSIX_PRIORITIZED_IO is defined (val is 200112)
sysconf says _POSIX_PRIORITIZED_IO = 200112

_POSIX_PRIORITIZED_SCHEDULING is undefined
no symbol for _POSIX_PRIORITIZED_SCHEDULING

_POSIX_RAW_SOCKETS is defined (val is 200112)
sysconf says _POSIX_RAW_SOCKETS = 200112

_POSIX_REALTIME_SIGNALS is defined (val is 200112)
sysconf says _POSIX_REALTIME_SIGNALS = 200112

_POSIX_SEMAPHORES is defined (val is 200112)
sysconf says _POSIX_SEMAPHORES = 200112

_POSIX_SHARED_MEMORY_OBJECTS is defined (val is 200112)
sysconf says _POSIX_SHARED_MEMORY_OBJECTS = 200112

_POSIX_SYNCHRONIZED_IO is defined (val is 200112)
sysconf says _POSIX_SYNCHRONIZED_IO = 200112

_POSIX_SPIN_LOCKS is defined (val is 200112)
sysconf says _POSIX_SPIN_LOCKS = 200112

_POSIX_SPAWN is defined (val is 200112)
sysconf says _POSIX_SPAWN = 200112

_POSIX_SPORADIC_SERVER is defined (val is -1)
sysconf says _POSIX_SPORADIC_SERVER = (no limit)

_POSIX_THREAD_CPUTIME is defined (val is 0)
sysconf says _POSIX_THREAD_CPUTIME = 200112

_POSIX_TRACE_EVENT_FILTER is defined (val is -1)
sysconf says _POSIX_TRACE_EVENT_FILTER = (no limit)

_POSIX_TIMEOUTS is defined (val is 200112)
sysconf says _POSIX_TIMEOUTS = 200112

_POSIX_TIMERS is defined (val is 200112)
sysconf says _POSIX_TIMERS = 200112

_POSIX_THREAD_PRIO_INHERIT is defined (val is 200112)
sysconf says _POSIX_THREAD_PRIO_INHERIT = 200112

_POSIX_THREAD_PRIO_PROTECT is defined (val is 200112)
sysconf says _POSIX_THREAD_PRIO_PROTECT = 200112

_POSIX_THREAD_PRIORITY_SCHEDULING is defined (val is 200112)
sysconf says _POSIX_THREAD_PRIORITY_SCHEDULING = 200112

_POSIX_TRACE is defined (val is -1)
sysconf says _POSIX_TRACE = (no limit)

_POSIX_TRACE_INHERIT is defined (val is -1)
sysconf says _POSIX_TRACE_INHERIT = (no limit)

_POSIX_TRACE_LOG is defined (val is -1)
sysconf says _POSIX_TRACE_LOG = (no limit)

_POSIX_THREAD_ATTR_STACKADDR is defined (val is 200112)
sysconf says _POSIX_THREAD_ATTR_STACKADDR = 200112

_POSIX_THREAD_SAFE_FUNCTIONS is defined (val is 200112)
sysconf says _POSIX_THREAD_SAFE_FUNCTIONS = 200112

_POSIX_THREAD_PROCESS_SHARED is defined (val is 200112)
sysconf says _POSIX_THREAD_PROCESS_SHARED = 200112

_POSIX_THREAD_SPORADIC_SERVER is defined (val is -1)
sysconf says _POSIX_THREAD_SPORADIC_SERVER = (no limit)

_POSIX_THREAD_ATTR_STACKSIZE is defined (val is 200112)
sysconf says _POSIX_THREAD_ATTR_STACKSIZE = 200112

_POSIX_THREADS is defined (val is 200112)
sysconf says _POSIX_THREADS = 200112

_POSIX_TYPED_MEMORY_OBJECTS is defined (val is -1)
sysconf says _POSIX_TYPED_MEMORY_OBJECTS = (no limit)

_XOPEN_UNIX is defined (val is 1)
sysconf says _XOPEN_UNIX = 1

_XOPEN_STREAMS is undefined
no symbol for _XOPEN_STREAMS

_XOPEN_CRYPT is defined (val is 1)
sysconf says _XOPEN_CRYPT = 1

_XOPEN_LEGACY is defined (val is 1)
sysconf says _XOPEN_LEGACY = 1

_XOPEN_REALTIME is defined (val is 1)
sysconf says _XOPEN_REALTIME = 1

_XOPEN_REALTIME_THREADS is defined (val is 1)
sysconf says _XOPEN_REALTIME_THREADS = 1

_POSIX_JOB_CONTROL is defined (val is 1)
sysconf says _POSIX_JOB_CONTROL = 1

_POSIX_READER_WRITER_LOCKS is defined (val is 200112)
sysconf says _POSIX_READER_WRITER_LOCKS = 200112

_POSIX_REGEXP is defined (val is 1)
sysconf says _POSIX_REGEXP = 1

_POSIX_SAVED_IDS is defined (val is 1)
sysconf says _POSIX_SAVED_IDS = 1

_POSIX_SHELL is defined (val is 1)
sysconf says _POSIX_SHELL = 1

_XOPEN_ENH_I18N is defined (val is 1)
sysconf says _XOPEN_ENH_I18N = 1

_XOPEN_SHM is defined (val is 1)
sysconf says _XOPEN_SHM = 1

_POSIX_VERSION is defined (val is 200112)
sysconf says _POSIX_VERSION = 200112

_XOPEN_VERSION is defined (val is 600)
sysconf says _XOPEN_VERSION = 600

_POSIX_CHOWN_RESTRICTED is defined (val is 1)
pathconf says _POSIX_CHOWN_RESTRICTED = 1

_POSIX_NO_TRUNC is defined (val is 1)
pathconf says _POSIX_NO_TRUNC = 1

_POSIX_VDISABLE is defined (val is 0)
pathconf says _POSIX_VDISABLE = 0

POSIX_ASYNC_IO is undefined
pathconf says POSIX_ASYNC_IO = (no limit)

POSIX_PRIO_IO is undefined
pathconf says POSIX_PRIO_IO = (no limit)

POSIX_SYNC_IO is undefined
pathconf says POSIX_SYNC_IO = (no limit)
----%<----
ARG_MAX defined to be 131072
ARG_MAX = 131072
no symbol for ATEXIT_MAX
ATEXIT_MAX = 2147483647
CHARCLASS_NAME_MAX defined to be 2048
CHARCLASS_NAME_MAX = 2048
no symbol for CHILD_MAX
CHILD_MAX = 8125
no symbol for CLOCKTICKSPERSECOND /*clock ticks/second*/
CLOCKTICKSPERSECOND /*clock ticks/second*/ = 100
COLL_WEIGHTS_MAX defined to be 255
COLL_WEIGHTS_MAX = 255
HOST_NAME_MAX defined to be 64
HOST_NAME_MAX = 64
IOV_MAX defined to be 1024
IOV_MAX = 1024
LINE_MAX defined to be 2048
LINE_MAX = 2048
LOGIN_NAME_MAX defined to be 256
LOGIN_NAME_MAX = 256
NGROUPS_MAX defined to be 65536
NGROUPS_MAX = 65536
no symbol for OPEN_MAX
OPEN_MAX = 1024
no symbol for PAGESIZE
PAGESIZE = 4096
no symbol for PAGE_SIZE
PAGE_SIZE = 4096
RE_DUP_MAX defined to be 32767
RE_DUP_MAX = 32767
no symbol for STREAM_MAX
STREAM_MAX = 16
no symbol for SYMLOOP_MAX
SYMLOOP_MAX = (no limit)
TTY_NAME_MAX defined to be 32
TTY_NAME_MAX = 32
no symbol for TZNAME_MAX
TZNAME_MAX = 6
MAX_CANON defined to be 255
MAX_CANON = 255
MAX_INPUT defined to be 255
MAX_INPUT = 255
no symbol for FILESIZEBITS
FILESIZEBITS = 64
no symbol for LINK_MAX
LINK_MAX = 32000
NAME_MAX defined to be 255
NAME_MAX = 255
PATH_MAX defined to be 4096
PATH_MAX = 4096
PIPE_BUF defined to be 4096
PIPE_BUF = 4096
no symbol for SYMLINK_MAX
SYMLINK_MAX = (no limit)

Sunday, November 30, 2008

ftw example for systems comparison.

ftw(3) has some inconsistencies.

For example ftw don't call its processing function for symlinks pointed from starting directory to starting directory, or its subdirs.

However, link to parent dir from starting directory reported in further walk.

From the other side, ftw checks and doesn't segfault in looping symlinks.

Checked under Linux 2.6.

source of example:

#include <ftw.h>
#include <stdio.h>
/*
* example for
* int ftw(const char *path, int (*fn)(const char *,
* const struct stat *ptr, int flag, int ndirs);
*/

int ffn(const char *path, const struct stat *ptr, int flag)
{
printf("Found\n path:%s\nflag%d\n", path, flag);
return 0;
}

int main(int argc, char ** argv)
{
char * inipath;
// example:
if (argv[1] && *argv[1])
{
inipath = argv[1];
}
else
{
fprintf(stderr,"usage: exftw PATH\n");
exit(-1);
}

if(ftw(inipath,ffn,20) != 0)
{
perror("ftw");exit(2);
}

return 0;
}

note: on my system it processed homedir with links for one minute.
when i have removed output by printf in ffn function from code, the time was just 1 second;

It looks like it is fast enough in comparison with output.

to check previous statement:


gcc exftw.c -o exftw
ln -s . dirlnsym
./exftw
./exftw | grep dirlnsym
# no reported dirlnsym reported
rm dirlnsym
ln -s ../../ dirlnsym
./exftw | grep dirlnsym
# ok; all reported and no looping

Tuesday, November 25, 2008

Signal delivery failed under FreeBSD.

Some unexpected staff from system well known for stability:
http://www.freebsd.org/cgi/query-pr.cgi?pr=129172

Strange, thу code cited under the link works fine under (Ubuntu 8.04) GNU/Linux.

Monday, September 29, 2008

build autotools project with gcov support

usage:


./configure CFLAGS='-fprofile-arcs -ftest-coverage'
./configure CFLAGS='-fprofile-arcs -ftest-coverage' CXXFLAGS='-fprofile-arcs -ftest-coverage'

cd src
./
gcov
vim
...
-: 25:
1: 26:if (argv[1][0]=='-') {
#####: 27:std::cout << "options not supported yet;" << std::endl;
#####: 28:exit(1);
-: 29:}
-: 30:
...


'#####' lines there indicate dead code in this run;
ciphers indicate number of times this peace of code was run.

Thursday, August 14, 2008

Cygwin pthreads exit causes access violation example

Example of stack overflow in cygwin.

While researched linking and AIX portability, tried example from there:
http://www.ibm.com/developerworks/aix/library/au-gnu.html?S_TACT=105AGX99&S_CMP=CP
(it is erroneous; simple mistakes were fixed):

After exit on cygwin it warns with access violation.

Executable than blocked (for removal).

Sunday, July 27, 2008

ddd installation on centOS



get ddd there:

http://ftp.gnu.org/gnu/ddd/

Through yum, install following package:


RPM Group : Development/Libraries
Source : openmotif-2.3.0-0.5.el5.src.rpm
Yum Group : Development/X Software Development
-> Type : Optional
Build Time : Sun May 25 06:14:11 2008
Install Time : Sun Jul 27 23:56:16 2008
License : Open Group Public License


and it dependencies

then

tar -xf ddd-.tar.gz
cd ddd
./configure
make
sudo make install

Tuesday, July 22, 2008

Gcc auto-vectorization

Code: vect_auto.c

#include <stdio.h>
#include <string.h>

int main()
{
int i,j,k,l;

int a[4096];
int b[4096];

memset((void *)a,0,4096);
memset((void *)b,0,4096);

for(i=0;i<4096;i++)
{
a[i] =i%67;
b[i]= i%87;
}

for(k=0;k<200000;k++)
for(i=0;i<4096;i++)
a[i] = a[i]+b[i];

l=0;

for(j=0;j<4096;j++)
{l=l+a[i];}

// printf("%d\n",l);
return l;
}



$ gcc -O3 -ftree-vectorize vect_auto.c -o vect_o

disasm:


0x0000000000400530 : movdqa (%rax,%rbp,1),%xmm0
0x0000000000400535 : paddd (%rax,%rbx,1),%xmm0
0x000000000040053a : movdqa %xmm0,(%rax,%rbx,1)

0x000000000040053f : add $0x10,%rax
0x0000000000400543 : cmp $0x4000,%rax
0x0000000000400549 : jne 0x400530



$ gcc -O3 vect_auto.c -o vect_o_no
disasm:

0x0000000000400528 : xor %edx,%edx
0x000000000040052a : nopw 0x0(%rax,%rax,1)
0x0000000000400530 : mov 0x0(%rbp,%rdx,4),%eax
0x0000000000400534 : add %eax,(%rbx,%rdx,4)
0x0000000000400537 : add $0x1,%rdx
0x000000000040053b : cmp $0x1000,%rdx
0x0000000000400542 : jne 0x400530

0x0000000000400544 : add $0x1,%ecx
0x0000000000400547 : cmp $0x30d40,%ecx
0x000000000040054d : jne 0x400528

[rtg@rtgCent vect]$ time ./vect_o_no

real 0m2.178s
user 0m2.128s
sys 0m0.003s
[rtg@rtgCent vect]$ time ./vect_o

real 0m0.867s
user 0m0.835s
sys 0m0.001s

vector operations used in the second executable, but gain in time is not such a big.

Tuesday, July 15, 2008

CPP (C++) vs C, std::string vs char[] : string processing benchmark

Very simple benchmark.
cpp source vs c source

This presents usage of string concatenation operators in c and c++.

C is up to 20 times faster on different compilers on small strings.
(However it just 3 times faster on my CentOS if outer loop increased up to 10000)


[rtg@rtgCent cpp_vs_c]$ g++ -O3 ppstr.cpp -o ppstr
[rtg@rtgCent cpp_vs_c]$ gcc -O3 cstr.c -o cstr
[rtg@rtgCent cpp_vs_c]$ sudo time nice -n -10 ./ppstr
[rtg@rtgCent cpp_vs_c]$ sudo time nice -n -10 ./cstr

(or xlC instead of g++ and gcc if you have IBM compiler)

Thursday, July 10, 2008

stupid vs smart, case vs ftable, algorithms vs processors, testing price vs gain

Actually, the task below can be easily solved by the paper and pen.

It was written in home at evening, just to measure performance as additional argument for rewriting stupid code for improving maintainability and performance of old legacy code.

Hypothetical example of the optimization of the following code was considered, and the return of the optimization effort (as resulting 'optimized' code) was timed.


     for(unsigned int i=0;i<65536;i++)
for(unsigned int j=0;j<65536;j++)
switch(j%15+1)
{
case 1:
f1();
break;
case 2:
f2();
...
}


The following are examples of performance, that can be achieved for integer massive operations due to different types of optimization.

Tried on AMD dual core DeskTop centOS, with gcc 4.1.3,
with optimization, and without.

4 types of code were considered:

Using switch(code) and case to define function to call;

Using case(code) and inlining function in call;

Using call to function by code ( fun(code) );

Just doing job without obfuscation by ftabs and cases.

Compilation done in following way:


[rtg@rtgCent cpp_exa]$ g++ -O3 case.cpp -o caseo
[rtg@rtgCent cpp_exa]$ g++ -O3 ftab.cpp -o ftabo
[rtg@rtgCent cpp_exa]$ g++ ftab.cpp -o ftab
[rtg@rtgCent cpp_exa]$ g++ case.cpp -o case
[rtg@rtgCent cpp_exa]$ su -


Some examples of output:

Red and green just presents timing for worst and best timing.


[root@rtgCent cpp_exa]# time nice -n -10 ./case
-458752

real 2m23.422s
user 2m23.205s
sys 0m0.112s

[root@rtgCent cpp_exa]# nice -n -10 ./caseo
-458752
[root@rtgCent cpp_exa]# time nice -n -10 ./caseo
-458752

real 1m3.688s
user 1m3.614s
sys 0m0.054s

[root@rtgCent cpp_exa]# time nice -n -10 ./ftab
-458752

real 1m41.664s
user 1m41.521s
sys 0m0.101s
[root@rtgCent cpp_exa]# time nice -n -10 ./ftabo
-458752

real 0m56.068s
user 0m56.004s
sys 0m0.047s
[root@rtgCent cpp_exa]# time nice -n -10 ./plaino
-458752

real 1m3.801s
user 1m3.732s
sys 0m0.047s

[root@rtgCent cpp_exa]# time nice -n -10 ./plain
-458752

real 1m53.174s
user 1m53.060s
sys 0m0.079s

[root@rtgCent cpp_exa]# time nice -n -10 ./opto
-458752

real 0m14.527s
user 0m14.509s
sys 0m0.014s

[root@rtgCent cpp_exa]# time nice -n -10 ./opt
-458752

real 0m31.956s
user 0m31.923s
sys 0m0.022s



It were just examples of the simpliest 'non algorithmic' optimization.

Simplified 'Algorithmic' optimization of the simplest case gives more than 100 time's faster output:


[root@rtgCent cpp_exa]# time nice -n -10 ./alg
-458752

real 0m0.011s
user 0m0.004s
sys 0m0.005s
[root@rtgCent cpp_exa]# time nice -n -10 ./algo
-458752

real 0m0.011s
user 0m0.003s
sys 0m0.005s



If you have some different opinion/results, please report in comments :)

By the way, who needs optimization today of critical systems, with today's pricing on retesting of system, and today modern cheap fast processors?


Code for examples:
alg.cpp
ftab.cpp
case.cpp
plain.cpp
opt.cpp


cpuinfo:

cpuinfo

Tuesday, July 8, 2008

c99 vectors, c++ example.

C99 vectors example .c file.
vector's some, and way to view as int's (through union).

C++ references as class members (with initialization, that should be done ), static counter of objects, array, and copy constructor (have to be?) .cpp file.

Thursday, July 3, 2008

setjmp, longjmp second parameter

setjmp, longjmp looks like continuations in functional languages.

This functions save/restore call contest as it does call/cc.

modified example from there:

http://publications.gbdirect.co.uk/c_book/chapter9/nonlocal_jumps.html


return values (second argument of longjmp example)


[rtg@rtgCent example]$ vi _jmp.c
[rtg@rtgCent example]$ gcc -g _jmp.c -o jmp
[rtg@rtgCent example]$ ./jmp
inside jmp: func
place retval=1
inside jmp: func2
place 2 retval=32


despite of longjmp second parameter set to zero, retval displayed as 1.

Here is example wich shows global and local variables in caller contest change.
_jmp2.c

Tuesday, April 15, 2008

refactoring

Appeared, that I have no suitable refactoring tool.

Started refactoring utility.
Platform is C, prototype in perl + postgres.

Perl appears great tool for prototyping of such tool(actually specific processor of set of files).
It provides you working prototype in times faster that it can be done in C.

First problems:

- Lack of time. I have only time when travelling between home and job, It takes about 1.5 hours, but not all time can be used for code input. That way version 1.0 only for Linux can take up to next new year. Actually it is possible that it would be never fixed because of changes in schedules, regime and load on paid job.

- Problem of platform choice. It have to be C because it is probably would be utility for GNU/Linux. Checked standards and appeared that C standard changed from last time I used pure C, but not C++. There is now C99 standard, and there is also draft standard with changes dated by this year.Also in GNU/Linux appeared used non standard GNU extensions of C. Decided to use C90, that way, because it is most commonly supported.

- Data structures. It is a lot of choices with pro's and con's. Decided to play with Perl prototype first. Using DS simple in implementation, with ability to change this to more fast but complex.

- Design questions. (sizes of structures, level of decomposition, libraries to use)

- License: GPL 2 (or 3?).

Saturday, March 22, 2008

javascript conditional function definition (c #ifdef ?)

C:


#ifdef MOZILLA_OS
#define _XHTML_
#endif

#ifdef _XHTML_
int print()
{
printf("<node />");
}
#endif

#ifndef _XHTML_
int print()
{
printf("<node></node>");
}
#endif



Javascript:


var OS="MOZILLA";
var XHTML;

if(OS=="MOZILLA")
{
XHTML=1;
} else {XHTML=0;};

if (XHTML)
{
function print() {document.write("<node />");};
} else {
function print() {document.write("<node></node>");};
};

Monday, February 25, 2008

Links: differences in syntax: Perl, tcl, Shell, C++, Python, Java, Javascript, Lisp

I have already mentioned in my post on comparing numbers and strings in shell, about problems of simultaneous use of different programming languages.

To conclude, having reference cards with description one language to another differences can be useful.

Listed is set of resources, intended for migration from one language to another.

Recommended (short,self-descriptive, useful):
languages comparison:
http://merd.sourceforge.net/pixel/language-study/syntax-across-languages/


Recommended, but not short:

Wikipedia page:
http://en.wikipedia.org/wiki/Comparison_of_programming_languages

Open directory listing for comparisons:
http://www.dmoz.org/Computers/Programming/Languages/Comparison_and_Review/

PLEAC - Programming Language Examples Alike Cookbook
Comparison of productivity of writing in different programming languages:
page.mi.fu-berlin.de/~prechelt/Biblio/jccpprtTR.pdf

Useful:
Java for c++ Programmers:
http://pages.cs.wisc.edu/~hasti/cs368/JavaTutorial/

http://triton.towson.edu/~mzimand/os/Lect2-java-tutorial.html
Lisp to javascript converter, descriptive.
http://javascript.crockford.com/little.html
Another one Lisp to Javascript converter written in javascript.( You can look into source to look into the code)
http://www.joeganley.com/code/jslisp.html

Comparison Python with Java, Lisp i.t.c.

http://wiki.python.org/moin/LanguageComparisons


Three scripting concurrents:
http://mjtsai.com/blog/2002/11/25/perl_vs_python_vs_ruby/

Accumulator generator in different languages:
http://www.paulgraham.com/accgen.html

Tcl vs. Python, with nice short examples

http://homepages.cwi.nl/~sjoerd/PythonVsTcl-old.html


This thread describes differences between bash and perl.
http://www.perlmonks.org/?node_id=661859

And at the end resource with language comparison in action (memory, speed, size).
http://shootout.alioth.debian.org/

Wednesday, February 13, 2008

C function calls order of computation

Demo of order of computation in the C program.

It shows case, where functions called for calculation of arguments called in order, different to left-to-right in which expression is writen.

gcc (GCC) 4.1.3 20070929 (prerelease)
used.


------------%<-----------------------
#include

int my_func(int arg1, char *arg2){
printf ("d=%d, s=%s\n", arg1, arg2);
return 0;
}

int main()
{
int i;
char *my;
my = "ad";
i = 5;
my_func(i,(my_func(1,"da"),my));
return my_func(1,"da");
}
------------>%-----------------------


gcc tst.c
./a.out

d=1, s=da
d=5, s=ad
d=1, s=da



modify my_fun:
-return 0;
+return arg1;


and main:
-my_func(i,(my_func(1,"da"),my));
+my_func((my_func(2,"two"),
+ my_func(3,"three"),
+ (my_func(4,"four"))), (my_func(5,"five"),
+ "six", "seven"));


recompile;
output will be:
d=5, s=five
d=2, s=two
d=3, s=three
d=4, s=four
d=4, s=seven
d=1, s=da


Second argument of outer call to my_func calculated first in the second example.

<---------->
This order is not specified in standard, and can be different for different compilers, and different for the same compiler.

Thats why functional style of programming in C and C++ is not acceptable option for me.

Friday, August 31, 2007

Iteration vs Recursion, Lisp vs C++, Functions vs Templates



1st chapter of SICP book task: recursive process in Scheme programming language without any loop forms (like for-each).

Implementation in Scheme:

;; recursive process
;; 1.11 from sicp
(define (f_rec1_11 n)
( cond ((< n 3) n )
(else (+
(f_rec1_11 (- n 1))
(f_rec1_11 (- n 2))
(f_rec1_11 (- n 3))))))

;; iterative (tail recursion)
(define (f_iter1_11 n) (f_i 0 1 2 (- n 2) ))

(define (f_i a0 a1 a2 count)
(if (= count 0) a2
(f_i a1 a2 (+ a0 a1 a2) (- count 1))))


Task in C: To implement without for, while, do, until, and goto output of numbers from one to 1000 in C.

#include <stdio.h>

int print_next_up(int in,int up)
{
printf("%d\n\n", ++in);
if (in >= up) return 0;
print_next_up(in,up);
}

int main()
{
print_next_up(0,1000);
return 0;
}


Example of the work of the C++ preprocessor:
Procedure in C++, printing numbers from 10 to 1 without even passing values to method calls or constructors. And recursion is in preprocessor.

#include <iostream>

template <int n> class printer
{
public :
printer() {
fun();
}
private:
int fun ()
{
std::cout << n << std::endl;
printer <n-1> myprinter;
}
};


template<> class printer<0>
{};

int main()
{
printer<10> a;
return 0;
}


And last, implementation of the task without loop constructs and recursion.

#include <iostream>

class my{
public:
static int a;
my()
{ std::cout << ++a << std::endl; }
};

int my::a = 0;

int main()
{
my myj[1000];
}