Changeset c1ea11b


Ignore:
Timestamp:
Jun 24, 2019, 11:12:01 AM (3 years ago)
Author:
Aaron Moss <a3moss@…>
Branches:
arm-eh, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
b58affe7, c1398e4
Parents:
18e683b (diff), 9e0a360 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Files:
4 added
49 edited

Legend:

Unmodified
Added
Removed
  • benchmark/Makefile.am

    r18e683b rc1ea11b  
    1111## Created On       : Sun May 31 09:08:15 2015
    1212## Last Modified By : Peter A. Buhr
    13 ## Last Modified On : Tue Nov  6 09:01:23 2018
    14 ## Update Count     : 26
     13## Last Modified On : Sun Jun 23 12:34:29 2019
     14## Update Count     : 52
    1515###############################################################################
    1616
     
    2121include $(top_srcdir)/src/cfa.make
    2222
    23 AM_CFLAGS = -O2 -Wall -Wextra -Werror -I$(srcdir) -lrt -pthread
     23AM_CFLAGS = -O2 -Wall -Wextra -I$(srcdir) -lrt -pthread # -Werror
    2424AM_CFAFLAGS = -quiet -nodebug -in-tree
    2525AM_UPPFLAGS = -quiet -nodebug -multi -std=c++14
     
    3131BENCH_V_JAVAC = $(__bench_v_JAVAC_$(__quiet))
    3232BENCH_V_UPP = $(__bench_v_UPP_$(__quiet))
     33BENCH_V_QTHREAD = $(__bench_v_QTHREAD_$(__quiet))
    3334
    3435__quiet = verbose
     
    4546__bench_v_JAVAC_verbose = $(AM_V_JAVAC)
    4647__bench_v_UPP_verbose = $(AM_V_UPP)
    47 
     48__bench_v_QTHREAD_verbose = $(AM_V_CC)
    4849
    4950
     
    5152REPEAT   = ${abs_top_builddir}/tools/repeat
    5253STATS    = ${abs_top_srcdir}/tools/stat.py
    53 repeats  = 30
     54repeats  = 3 # 30
    5455skipcompile = no
    5556TIME_FORMAT = "%E"
     
    124125
    125126ctxswitch.csv:
    126         @echo "coroutine,thread" > $@
     127        @echo "generator,coroutine,thread" > $@
     128        @+make ctxswitch-cfa_generator.runquiet >> $@ && echo -n ',' >> $@
    127129        @+make ctxswitch-cfa_coroutine.runquiet >> $@ && echo -n ',' >> $@
    128130        @+make ctxswitch-cfa_thread.runquiet >> $@
     
    153155        $(BENCH_V_CC)$(COMPILE) -DBENCH_N=500000000  $(srcdir)/fetch_add.c
    154156
     157ttst_lock$(EXEEXT):
     158        $(BENCH_V_CC)$(COMPILE) -DBENCH_N=500000000  $(srcdir)/ttst_lock.c
     159
    155160tls-fetch_add$(EXEEXT):
    156161        $(BENCH_V_CC)$(COMPILE) -DBENCH_N=500000000  $(srcdir)/tls-fetch_add.c
     
    161166        function.run                    \
    162167        fetch_add.run                   \
     168        ttst_lock.run                   \
    163169        tls-fetch_add.run                       \
    164170        ctxswitch-pthread.run           \
     171        ctxswitch-cfa_generator.run     \
    165172        ctxswitch-cfa_coroutine.run     \
    166173        ctxswitch-cfa_thread.run        \
     
    169176        ctxswitch-upp_thread.run        \
    170177        ctxswitch-goroutine.run         \
    171         ctxswitch-java_thread.run
     178        ctxswitch-java_thread.run       \
     179        ctxswitch-qthreads.run
     180
    172181
    173182if WITH_LIBFIBRE
     
    188197ctxswitch-pthread$(EXEEXT):
    189198        $(BENCH_V_CC)$(COMPILE)    -DBENCH_N=50000000 $(srcdir)/ctxswitch/pthreads.c
     199
     200ctxswitch-cfa_generator$(EXEEXT):
     201        $(BENCH_V_CFA)$(CFACOMPILE) -DBENCH_N=50000000 $(srcdir)/ctxswitch/cfa_gen.cfa
    190202
    191203ctxswitch-cfa_coroutine$(EXEEXT):
     
    212224        @echo "java JavaThread" >> a.out
    213225        @chmod a+x a.out
     226
     227ctxswitch-qthreads$(EXEEXT):
     228        $(BENCH_V_QTHREADS)$(COMPILE) -DBENCH_N=50000000 -I/u/pabuhr/software/qthreads/include -L/u/pabuhr/software/qthreads/lib -Xlinker -R/u/pabuhr/software/qthreads/lib $(srcdir)/ctxswitch/qthreads.c -lqthread
    214229
    215230## =========================================================================================================
     
    305320        creation-upp_thread.run                 \
    306321        creation-goroutine.run                  \
    307         creation-java_thread.run
     322        creation-java_thread.run                \
     323        creation-qthreads.run
    308324
    309325creation-cfa_coroutine$(EXEEXT):
     
    333349        @echo "java JavaThread" >> a.out
    334350        @chmod a+x a.out
     351
     352creation-qthreads$(EXEEXT):
     353        $(BENCH_V_QTHREADS)$(COMPILE) -DBENCH_N=50000000 -I/u/pabuhr/software/qthreads/include -L/u/pabuhr/software/qthreads/lib -Xlinker -R/u/pabuhr/software/qthreads/lib $(srcdir)/ctxswitch/qthreads.c -lqthread
    335354
    336355## =========================================================================================================
     
    375394compile-typeof$(EXEEXT):
    376395        @$(CFACOMPILE) -fsyntax-only -w $(testdir)/typeof.cfa
    377 
  • benchmark/Makefile.in

    r18e683b rc1ea11b  
    371371
    372372# applies to both programs
    373 AM_CFLAGS = -O2 -Wall -Wextra -Werror -I$(srcdir) -lrt -pthread
     373AM_CFLAGS = -O2 -Wall -Wextra -I$(srcdir) -lrt -pthread # -Werror
    374374AM_CFAFLAGS = -quiet -nodebug -in-tree
    375375AM_UPPFLAGS = -quiet -nodebug -multi -std=c++14
     
    380380BENCH_V_JAVAC = $(__bench_v_JAVAC_$(__quiet))
    381381BENCH_V_UPP = $(__bench_v_UPP_$(__quiet))
     382BENCH_V_QTHREAD = $(__bench_v_QTHREAD_$(__quiet))
    382383__quiet = verbose
    383384__bench_v_CC_quiet = @
     
    393394__bench_v_JAVAC_verbose = $(AM_V_JAVAC)
    394395__bench_v_UPP_verbose = $(AM_V_UPP)
     396__bench_v_QTHREAD_verbose = $(AM_V_CC)
    395397TOOLSDIR = ${abs_top_builddir}/tools/
    396398REPEAT = ${abs_top_builddir}/tools/repeat
    397399STATS = ${abs_top_srcdir}/tools/stat.py
    398 repeats = 30
     400repeats = 3 # 30
    399401skipcompile = no
    400402TIME_FORMAT = "%E"
     
    402404dummy_SOURCES = dummyC.c dummyCXX.cpp
    403405FIX_NEW_LINES = cat $@ | tr "\n" "\t" | sed -r 's/\t,/,/' | tr "\t" "\n" > $@
    404 CTXSWITCH_DEPEND = loop.run function.run fetch_add.run \
     406CTXSWITCH_DEPEND = loop.run function.run fetch_add.run ttst_lock.run \
    405407        tls-fetch_add.run ctxswitch-pthread.run \
    406         ctxswitch-cfa_coroutine.run ctxswitch-cfa_thread.run \
    407         ctxswitch-cfa_thread2.run ctxswitch-upp_coroutine.run \
    408         ctxswitch-upp_thread.run ctxswitch-goroutine.run \
    409         ctxswitch-java_thread.run $(am__append_1)
     408        ctxswitch-cfa_generator.run ctxswitch-cfa_coroutine.run \
     409        ctxswitch-cfa_thread.run ctxswitch-cfa_thread2.run \
     410        ctxswitch-upp_coroutine.run ctxswitch-upp_thread.run \
     411        ctxswitch-goroutine.run ctxswitch-java_thread.run \
     412        ctxswitch-qthreads.run $(am__append_1)
    410413testdir = $(top_srcdir)/tests
    411414all: all-am
     
    784787
    785788ctxswitch.csv:
    786         @echo "coroutine,thread" > $@
     789        @echo "generator,coroutine,thread" > $@
     790        @+make ctxswitch-cfa_generator.runquiet >> $@ && echo -n ',' >> $@
    787791        @+make ctxswitch-cfa_coroutine.runquiet >> $@ && echo -n ',' >> $@
    788792        @+make ctxswitch-cfa_thread.runquiet >> $@
     
    812816        $(BENCH_V_CC)$(COMPILE) -DBENCH_N=500000000  $(srcdir)/fetch_add.c
    813817
     818ttst_lock$(EXEEXT):
     819        $(BENCH_V_CC)$(COMPILE) -DBENCH_N=500000000  $(srcdir)/ttst_lock.c
     820
    814821tls-fetch_add$(EXEEXT):
    815822        $(BENCH_V_CC)$(COMPILE) -DBENCH_N=500000000  $(srcdir)/tls-fetch_add.c
     
    825832ctxswitch-pthread$(EXEEXT):
    826833        $(BENCH_V_CC)$(COMPILE)    -DBENCH_N=50000000 $(srcdir)/ctxswitch/pthreads.c
     834
     835ctxswitch-cfa_generator$(EXEEXT):
     836        $(BENCH_V_CFA)$(CFACOMPILE) -DBENCH_N=50000000 $(srcdir)/ctxswitch/cfa_gen.cfa
    827837
    828838ctxswitch-cfa_coroutine$(EXEEXT):
     
    849859        @echo "java JavaThread" >> a.out
    850860        @chmod a+x a.out
     861
     862ctxswitch-qthreads$(EXEEXT):
     863        $(BENCH_V_QTHREADS)$(COMPILE) -DBENCH_N=50000000 -I/u/pabuhr/software/qthreads/include -L/u/pabuhr/software/qthreads/lib -Xlinker -R/u/pabuhr/software/qthreads/lib $(srcdir)/ctxswitch/qthreads.c -lqthread
    851864
    852865mutex$(EXEEXT) :\
     
    937950        creation-upp_thread.run                 \
    938951        creation-goroutine.run                  \
    939         creation-java_thread.run
     952        creation-java_thread.run                \
     953        creation-qthreads.run
    940954
    941955creation-cfa_coroutine$(EXEEXT):
     
    965979        @echo "java JavaThread" >> a.out
    966980        @chmod a+x a.out
     981
     982creation-qthreads$(EXEEXT):
     983        $(BENCH_V_QTHREADS)$(COMPILE) -DBENCH_N=50000000 -I/u/pabuhr/software/qthreads/include -L/u/pabuhr/software/qthreads/lib -Xlinker -R/u/pabuhr/software/qthreads/lib $(srcdir)/ctxswitch/qthreads.c -lqthread
    967984
    968985compile$(EXEEXT) :\
  • benchmark/bench.h

    r18e683b rc1ea11b  
    4545        statement;                                      \
    4646        EndTime = bench_time();                 \
    47         unsigned long long int output =         \
    48         ( EndTime - StartTime ) / n;
     47        double output =         \
     48            (double)( EndTime - StartTime ) / n;
    4949
    5050#if defined(__cforall)
  • benchmark/creation/cfa_cor.cfa

    r18e683b rc1ea11b  
    1010#endif
    1111}
    12 void main(MyCoroutine & this) {}
     12void main(MyCoroutine &) {}
    1313
    1414int main(int argc, char* argv[]) {
    1515        BENCH(
    16                 for (size_t i = 0; i < n; i++) {
     16                for ( i; n ) {
    1717                        MyCoroutine m;
    1818                },
     
    2020        )
    2121
    22         printf("%llu\n", result);
     22        printf("%g\n", result);
    2323}
  • benchmark/creation/cfa_thrd.cfa

    r18e683b rc1ea11b  
    55
    66thread MyThread {};
    7 void main(MyThread & this) {}
     7void main(MyThread &) {}
    88
    99int main(int argc, char* argv[]) {
    1010        BENCH(
    11                 for (size_t i = 0; i < n; i++) {
     11                for ( i; n ) {
    1212                        MyThread m;
    1313                },
     
    1515        )
    1616
    17         printf("%llu\n", result);
     17        printf("%g\n", result);
    1818}
  • benchmark/creation/pthreads.c

    r18e683b rc1ea11b  
    2525        )
    2626
    27         printf("%llu\n", result);
     27        printf("%g\n", result);
    2828}
  • benchmark/creation/upp_cor.cc

    r18e683b rc1ea11b  
    1515        )
    1616
    17         printf("%llu\n", result);
     17        printf("%g\n", result);
    1818}
  • benchmark/creation/upp_thrd.cc

    r18e683b rc1ea11b  
    1515        )
    1616
    17         printf("%llu\n", result);
     17        printf("%g\n", result);
    1818}
  • benchmark/ctxswitch/cfa_cor.cfa

    r18e683b rc1ea11b  
    1 #include <stdio.h>
    21#include <kernel.hfa>
    32#include <thread.hfa>
     
    2120
    2221        BENCH(
    23                 for (size_t i = 0; i < n; i++) {
     22                for ( i; n ) {
    2423                        resume( s );
    2524                },
     
    2726        )
    2827
    29         printf("%llu\n", result);
     28        printf("%g\n", result);
    3029}
  • benchmark/ctxswitch/cfa_cor_then.cfa

    r18e683b rc1ea11b  
    1 #include <stdio.h>
    21#include <kernel.hfa>
    32#include <thread.hfa>
     
    2322
    2423        BENCH(
    25                 for (size_t i = 0; i < n; i++) {
     24                for ( i; n ) {
    2625                        resume( s );
    2726                },
     
    2928        )
    3029
    31         printf("%llu\n", result);
     30        printf("%g\n", result);
    3231}
  • benchmark/ctxswitch/cfa_thrd.cfa

    r18e683b rc1ea11b  
    1 #include <stdio.h>
    21#include <thread.hfa>
    32
     
    65int main(int argc, char* argv[]) {
    76        BENCH(
    8                 for (size_t i = 0; i < n; i++) {
     7                for ( i; n ) {
    98                        yield();
    109                },
     
    1211        )
    1312
    14         printf("%llu\n", result);
     13        printf("%g\n", result);
    1514}
  • benchmark/ctxswitch/cfa_thrd2.cfa

    r18e683b rc1ea11b  
    1 #include <stdio.h>
    21#include <thread.hfa>
    32
     
    1716        Fibre f1;
    1817        BENCH(
    19                 for (size_t i = 0; i < n; i++) {
     18                for ( i; n ) {
    2019                        yield();
    2120                },
     
    2322        )
    2423
    25         printf("%llu\n", result);
     24        printf("%g\n", result);
    2625        done = true;
    2726        return 0;
  • benchmark/ctxswitch/kos_fibre.cpp

    r18e683b rc1ea11b  
    1010                result
    1111        )
    12         printf("%llu\n", result);
     12        printf("%g\n", result);
    1313        return 0;
    1414}
  • benchmark/ctxswitch/kos_fibre2.cpp

    r18e683b rc1ea11b  
    1919                result
    2020        )
    21         printf("%llu\n", result);
     21        printf("%g\n", result);
    2222        done = true;
    2323        Fibre::yield();
  • benchmark/ctxswitch/pthreads.c

    r18e683b rc1ea11b  
    1414        )
    1515
    16         printf("%llu\n", result);
     16        printf("%g\n", result);
    1717}
  • benchmark/ctxswitch/upp_cor.cc

    r18e683b rc1ea11b  
    3030        )
    3131
    32         printf("%llu\n", result);
     32        printf("%g\n", result);
    3333}
  • benchmark/ctxswitch/upp_thrd.cc

    r18e683b rc1ea11b  
    1111        )
    1212
    13         printf("%llu\n", result);
     13        printf("%g\n", result);
    1414}
  • benchmark/fetch_add.c

    r18e683b rc1ea11b  
    1919        )
    2020
    21         printf("%llu\n", result);
     21        printf("%g\n", result);
    2222}
  • benchmark/function.c

    r18e683b rc1ea11b  
    1515        )
    1616
    17         printf("%llu\n", result);
     17        printf("%g\n", result);
    1818}
  • benchmark/loop.c

    r18e683b rc1ea11b  
    1111        )
    1212
    13         printf("%llu\n", result);
     13        printf("%g\n", result);
    1414}
  • benchmark/mutex/cfa1.cfa

    r18e683b rc1ea11b  
    1010        M m;
    1111        BENCH(
    12                 for (size_t i = 0; i < n; i++) {
     12                for ( i; n ) {
    1313                        call(m);
    1414                },
     
    1616        )
    1717
    18         printf("%llu\n", result);
     18        printf("%g\n", result);
    1919}
  • benchmark/mutex/cfa2.cfa

    r18e683b rc1ea11b  
    1010        M m1, m2;
    1111        BENCH(
    12                 for (size_t i = 0; i < n; i++) {
     12                for ( i; n ) {
    1313                        call(m1, m2);
    1414                },
     
    1616        )
    1717
    18         printf("%llu\n", result);
     18        printf("%g\n", result);
    1919}
  • benchmark/mutex/cfa4.cfa

    r18e683b rc1ea11b  
    1111        M m1, m2, m3, m4;
    1212        BENCH(
    13                 for (size_t i = 0; i < n; i++) {
     13                for ( i; n ) {
    1414                        call(m1, m2, m3, m4);
    1515                },
     
    1717        )
    1818
    19         printf("%llu\n", result);
     19        printf("%g\n", result);
    2020}
  • benchmark/mutex/pthreads.c

    r18e683b rc1ea11b  
    1919        )
    2020
    21         printf("%llu\n", result);
     21        printf("%g\n", result);
    2222}
  • benchmark/mutex/upp.cc

    r18e683b rc1ea11b  
    1717        )
    1818
    19         printf("%llu\n", result);
     19        printf("%g\n", result);
    2020}
  • benchmark/schedext/cfa1.cfa

    r18e683b rc1ea11b  
    1818        go = 1;
    1919        BENCH(
    20                 for (size_t i = 0; i < n; i++) {
     20                for ( i; n ) {
    2121                        waitfor(call, a1);
    2222                },
     
    2424        )
    2525
    26         printf("%llu\n", result);
     26        printf("%g\n", result);
    2727        go = 0;
    2828        return 0;
     
    3131thread T {};
    3232void ^?{}( T & mutex this ) {}
    33 void main( T & this ) {
     33void main( T & ) {
    3434        while(go == 0) { yield(); }
    3535        while(go == 1) { call(m1); }
     
    3737}
    3838
    39 int main(int margc, char* margv[]) {
    40         argc = margc;
    41         argv = margv;
     39int main(__attribute__((unused)) int argc, __attribute__((unused)) char* argv[]) {
    4240        T t;
    4341        return wait(m1);
  • benchmark/schedext/cfa2.cfa

    r18e683b rc1ea11b  
    1818        go = 1;
    1919        BENCH(
    20                 for (size_t i = 0; i < n; i++) {
     20                for ( i; n ) {
    2121                        waitfor(call, a1, a2);
    2222                },
     
    2424        )
    2525
    26         printf("%llu\n", result);
     26        printf("%g\n", result);
    2727        go = 0;
    2828        return 0;
     
    3131thread T {};
    3232void ^?{}( T & mutex this ) {}
    33 void main( T & this ) {
     33void main( T & ) {
    3434        while(go == 0) { yield(); }
    3535        while(go == 1) { call(m1, m2); }
     
    3737}
    3838
    39 int main(int margc, char* margv[]) {
    40         argc = margc;
    41         argv = margv;
     39int main(__attribute__((unused)) int argc, __attribute__((unused)) char* argv[]) {
    4240        T t;
    4341        return wait(m1, m2);
  • benchmark/schedext/cfa4.cfa

    r18e683b rc1ea11b  
    1818        go = 1;
    1919        BENCH(
    20                 for (size_t i = 0; i < n; i++) {
     20                for ( i; n ) {
    2121                        waitfor(call, a1, a2, a3, a4);
    2222                },
     
    2424        )
    2525
    26         printf("%llu\n", result);
     26        printf("%g\n", result);
    2727        go = 0;
    2828        return 0;
     
    3131thread T {};
    3232void ^?{}( T & mutex this ) {}
    33 void main( T & this ) {
     33void main( T & ) {
    3434        while(go == 0) { yield(); }
    3535        while(go == 1) { call(m1, m2, m3, m4); }
     
    3737}
    3838
    39 int main(int margc, char* margv[]) {
    40         argc = margc;
    41         argv = margv;
     39int main(__attribute__((unused)) int argc, __attribute__((unused)) char* argv[]) {
    4240        T t;
    4341        return wait(m1, m2, m3, m4);
  • benchmark/schedext/upp.cc

    r18e683b rc1ea11b  
    2020                )
    2121
    22                 printf("%llu\n", result);
     22                printf("%g\n", result);
    2323                go = 0;
    2424                return 0;
  • benchmark/schedint/cfa1.cfa

    r18e683b rc1ea11b  
    2121        go = 1;
    2222        BENCH(
    23                 for (size_t i = 0; i < n; i++) {
     23                for ( i; n ) {
    2424                        wait(c);
    2525                },
     
    2727        )
    2828
    29         printf("%llu\n", result);
     29        printf("%g\n", result);
    3030        go = 0;
    3131        return 0;
     
    3333
    3434thread T {};
    35 void ^?{}( T & mutex this ) {}
    36 void main( T & this ) {
     35void ^?{}( T & mutex ) {}
     36void main( T & ) {
    3737        while(go == 0) { yield(); }
    3838        while(go == 1) { call(m1); }
     
    4040}
    4141
    42 int main(int margc, char* margv[]) {
    43         argc = margc;
    44         argv = margv;
     42int main(__attribute__((unused)) int argc, __attribute__((unused)) char* argv[]) {
    4543        T t;
    4644        return wait(m1);
  • benchmark/schedint/cfa2.cfa

    r18e683b rc1ea11b  
    2121        go = 1;
    2222        BENCH(
    23                 for (size_t i = 0; i < n; i++) {
     23                for ( i; n ) {
    2424                        wait(c);
    2525                },
     
    2727        )
    2828
    29         printf("%llu\n", result);
     29        printf("%g\n", result);
    3030        go = 0;
    3131        return 0;
     
    3434thread T {};
    3535void ^?{}( T & mutex this ) {}
    36 void main( T & this ) {
     36void main( T & ) {
    3737        while(go == 0) { yield(); }
    3838        while(go == 1) { call(m1, m2); }
     
    4040}
    4141
    42 int main(int margc, char* margv[]) {
    43         argc = margc;
    44         argv = margv;
     42int main(__attribute__((unused)) int argc, __attribute__((unused)) char* argv[]) {
    4543        T t;
    4644        return wait(m1, m2);
  • benchmark/schedint/cfa4.cfa

    r18e683b rc1ea11b  
    2121        go = 1;
    2222        BENCH(
    23                 for (size_t i = 0; i < n; i++) {
     23                for ( i; n ) {
    2424                        wait(c);
    2525                },
     
    2727        )
    2828
    29         printf("%llu\n", result);
     29        printf("%g\n", result);
    3030        go = 0;
    3131        return 0;
     
    3434thread T {};
    3535void ^?{}( T & mutex this ) {}
    36 void main( T & this ) {
     36void main( T & ) {
    3737        while(go == 0) { yield(); }
    3838        while(go == 1) { call(m1, m2, m3, m4); }
     
    4040}
    4141
    42 int main(int margc, char* margv[]) {
    43         argc = margc;
    44         argv = margv;
     42int main(__attribute__((unused)) int argc, __attribute__((unused)) char* argv[]) {
    4543        T t;
    4644        return wait(m1, m2, m3, m4);
  • benchmark/schedint/pthreads.c

    r18e683b rc1ea11b  
    2727        )
    2828
    29         printf("%llu\n", result);
     29        printf("%g\n", result);
    3030        go = 0;
    3131        pthread_mutex_unlock(&m);
     
    3333}
    3434
    35 void* thread_main(void * a) {
     35void* thread_main(__attribute__((unused)) void * arg ) {
    3636        while(go == 0) { sched_yield(); }
    3737        while(go == 1) { call(); }
     
    3939}
    4040
    41 int main(int margc, char* margv[]) {
    42         argc = margc;
    43         argv = margv;
     41int main(__attribute__((unused)) int argc, __attribute__((unused)) char* argv[]) {
    4442        pthread_t thread;
    4543        if (pthread_create(&thread, NULL, thread_main, NULL) < 0) {
  • benchmark/schedint/upp.cc

    r18e683b rc1ea11b  
    2323                )
    2424
    25                 printf("%llu\n", result);
     25                printf("%g\n", result);
    2626                go = 0;
    2727                return 0;
     
    3939};
    4040
    41 int main(int margc, char* margv[]) {
    42         argc = margc;
    43         argv = margv;
     41int main(__attribute__((unused)) int argc, __attribute__((unused)) char* argv[]) {
    4442        T t;
    4543        return m.wait();
  • benchmark/tls-fetch_add.c

    r18e683b rc1ea11b  
    2424        )
    2525
    26         printf("%llu\n", result);
     26        printf("%g\n", result);
    2727}
  • doc/bibliography/pl.bib

    r18e683b rc1ea11b  
    948948    author      = {{\textsf{C}{$\mathbf{\forall}$} Features}},
    949949    howpublished= {\href{https://plg.uwaterloo.ca/~cforall/features}{https://\-plg.uwaterloo.ca/\-$\sim$cforall/\-features}},
     950}
     951
     952@misc{CforallBenchMarks,
     953    contributer = {pabuhr@plg},
     954    key         = {Cforall Benchmarks},
     955    author      = {{\textsf{C}{$\mathbf{\forall}$} Benchmarks}},
     956    howpublished= {\href{https://plg.uwaterloo.ca/~cforall/benchmarks}{https://\-plg.uwaterloo.ca/\-$\sim$cforall/\-benchmarks}},
    950957}
    951958
     
    19191926    year        = 1965,
    19201927    note        = {Reprinted in \cite{Genuys68} pp. 43--112.}
     1928}
     1929
     1930@inproceedings{Adya02,
     1931    contributer = {pabuhr@plg},
     1932    author      = {Adya, Atul and Howell, Jon and Theimer, Marvin and Bolosky, William J. and Douceur, John R.},
     1933    title       = {Cooperative Task Management Without Manual Stack Management},
     1934    booktitle   = {Proceedings of the General Track of the Annual Conference on USENIX Annual Technical Conference},
     1935    series      = {ATEC '02},
     1936    year        = {2002},
     1937    pages       = {289-302},
     1938    publisher   = {USENIX Association},
     1939    address     = {Berkeley, CA, USA},
     1940}
     1941
     1942@misc{CoroutineTS,
     1943    keywords    = {Coroutines TS, C++20, working draft},
     1944    contributer = {pabuhr@plg},
     1945    author      = {Gor Nishanov},
     1946    title       = {Merge Coroutines TS into C++20 Working Draft},
     1947    year        = 2019,
     1948    month       = feb,
     1949    howpublished= {\href{http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0912r5.html}
     1950                  {http://\-www.open-std.org/\-jtc1/\-sc22/\-wg21/\-docs/\-papers/\-2019/p0912r5.html}},
    19211951}
    19221952
     
    43594389}
    43604390
     4391
    43614392@article{Liskov86,
    43624393    keywords    = {synchronous communication, concurrency},
     
    43714402    year        = {},
    43724403    pages       = {},
     4404}
     4405
     4406@misc{libdill,
     4407    keywords    = {libdill/libmill Thread Library},
     4408    contributer = {pabuhr@plg},
     4409    author      = {Alex Cornejo, et al},
     4410    title       = {libdill Thread Library},
     4411    year        = 2019,
     4412    howpublished= {\href{http://libdill.org/libdill-2.14.tar.gz}
     4413                  {http://\-libdill.org/\-libdill-2.14.tar.gz}},
    43734414}
    43744415
     
    44934534    year        = 2016,
    44944535    howpublished= {\href{http://blog.reverberate.org/2016/01/making-arbitrarily-large-binaries-from.html}
    4495                   {
    4496           {http://blog.reverberate.org/\-2016/\-01/\-making-arbitrarily-large-binaries-from.html}
    4497           }},
     4536                  {http://blog.reverberate.org/\-2016/\-01/\-making-arbitrarily-large-binaries-from.html}},
    44984537    optnote     = {Accessed: 2016-09},
    44994538}
     
    45174556        trivial changes to the source code of the library.
    45184557    }
     4558}
     4559
     4560@misc{Marcel,
     4561    keywords    = {Marcel Thread Library},
     4562    contributer = {pabuhr@plg},
     4563    author      = {Gabriel Antoniu, et al},
     4564    title       = {Marcel Thread Library},
     4565    year        = 2011,
     4566    howpublished= {\href{https://gforge.inria.fr/frs/download.php/file/28643/marcel-2.99.3.tar.gz}
     4567                  {https://\-gforge.inria.fr/\-frs/\-download.php/\-file/\-28643/\-marcel-2.99.3.tar.gz}},
    45194568}
    45204569
  • doc/papers/AMA/AMA-stix/ama/WileyNJD-v2.cls

    r18e683b rc1ea11b  
    24442444     \@afterheading}
    24452445
    2446 \renewcommand\section{\@startsection{section}{1}{\z@}{-27pt \@plus -2pt \@minus -2pt}{12\p@}{\sectionfont}}%
    2447 \renewcommand\subsection{\@startsection{subsection}{2}{\z@}{-23pt \@plus -2pt \@minus -2pt}{5\p@}{\subsectionfont}}%
     2446\renewcommand\section{\@startsection{section}{1}{\z@}{-25pt \@plus -2pt \@minus -2pt}{12\p@}{\sectionfont}}%
     2447\renewcommand\subsection{\@startsection{subsection}{2}{\z@}{-22pt \@plus -2pt \@minus -2pt}{5\p@}{\subsectionfont}}%
    24482448\renewcommand\subsubsection{\@startsection{subsubsection}{3}{\z@}{-20pt \@plus -2pt \@minus -2pt}{2\p@}{\subsubsectionfont}}%
    24492449%
  • doc/papers/concurrency/Paper.tex

    r18e683b rc1ea11b  
    157157                __float80, float80, __float128, float128, forall, ftype, generator, _Generic, _Imaginary, __imag, __imag__,
    158158                inline, __inline, __inline__, __int128, int128, __label__, monitor, mutex, _Noreturn, one_t, or,
    159                 otype, restrict, __restrict, __restrict__, __signed, __signed__, _Static_assert, suspend, thread,
     159                otype, restrict, __restrict, __restrict__, __signed, __signed__, _Static_assert, thread,
    160160                _Thread_local, throw, throwResume, timeout, trait, try, ttype, typeof, __typeof, __typeof__,
    161161                virtual, __volatile, __volatile__, waitfor, when, with, zero_t},
     
    303303However, \Celeven concurrency is largely wrappers for a subset of the pthreads library~\cite{Butenhof97,Pthreads}, and \Celeven and pthreads concurrency is simple, based on thread fork/join in a function and a few locks, which is low-level and error prone;
    304304no high-level language concurrency features are defined.
    305 Interestingly, almost a decade after publication of the \Celeven standard, neither gcc-8, clang-8 nor msvc-19 (most recent versions) support the \Celeven include @threads.h@, indicating little interest in the C11 concurrency approach.
     305Interestingly, almost a decade after publication of the \Celeven standard, neither gcc-8, clang-9 nor msvc-19 (most recent versions) support the \Celeven include @threads.h@, indicating little interest in the C11 concurrency approach.
    306306Finally, while the \Celeven standard does not state a threading model, the historical association with pthreads suggests implementations would adopt kernel-level threading (1:1)~\cite{ThreadModel}.
    307307
     
    313313From 2000 onwards, languages like Go~\cite{Go}, Erlang~\cite{Erlang}, Haskell~\cite{Haskell}, D~\cite{D}, and \uC~\cite{uC++,uC++book} have championed the M:N user-threading model, and many user-threading libraries have appeared~\cite{Qthreads,MPC,Marcel}, including putting green threads back into Java~\cite{Quasar}.
    314314The main argument for user-level threading is that they are lighter weight than kernel threads (locking and context switching do not cross the kernel boundary), so there is less restriction on programming styles that encourage large numbers of threads performing medium work-units to facilitate load balancing by the runtime~\cite{Verch12}.
    315 As well, user-threading facilitates a simpler concurrency approach using thread objects that leverage sequential patterns versus events with call-backs~\cite{vonBehren03}.
     315As well, user-threading facilitates a simpler concurrency approach using thread objects that leverage sequential patterns versus events with call-backs~\cite{Adya02,vonBehren03}.
    316316Finally, performant user-threading implementations (both time and space) meet or exceed direct kernel-threading implementations, while achieving the programming advantages of high concurrency levels and safety.
    317317
     
    613613Finally, an explicit generator type provides both design and performance benefits, such as multiple type-safe interface functions taking and returning arbitrary types.
    614614\begin{cfa}
    615 int ?()( Fib & fib ) with( fib ) { return `resume( fib )`.fn; }   // function-call interface
    616 int ?()( Fib & fib, int N ) with( fib ) { for ( N - 1 ) `fib()`; return `fib()`; }   // use simple interface
    617 double ?()( Fib & fib ) with( fib ) { return (int)`fib()` / 3.14159; } // cast prevents recursive call
    618 sout | (int)f1() | (double)f1() | f2( 2 );   // simple interface, cast selects call based on return type, step 2 values
     615int ?()( Fib & fib ) { return `resume( fib )`.fn; } $\C[3.9in]{// function-call interface}$
     616int ?()( Fib & fib, int N ) { for ( N - 1 ) `fib()`; return `fib()`; } $\C{// use function-call interface to skip N values}$
     617double ?()( Fib & fib ) { return (int)`fib()` / 3.14159; } $\C{// different return type, cast prevents recursive call}\CRT$
     618sout | (int)f1() | (double)f1() | f2( 2 ); // alternative interface, cast selects call based on return type, step 2 values
    619619\end{cfa}
    620620Now, the generator can be a separately-compiled opaque-type only accessed through its interface functions.
     
    628628With respect to safety, we believe static analysis can discriminate local state from temporary variables in a generator, \ie variable usage spanning @suspend@, and generate a compile-time error.
    629629Finally, our current experience is that most generator problems have simple data state, including local state, but complex execution state, so the burden of creating the generator type is small.
    630 As well, C programmers are not afraid with this kind of semantic programming requirement, if it results in very small, fast generators.
     630As well, C programmers are not afraid of this kind of semantic programming requirement, if it results in very small, fast generators.
    631631
    632632Figure~\ref{f:CFAFormatGen} shows an asymmetric \newterm{input generator}, @Fmt@, for restructuring text into groups of characters of fixed-size blocks, \ie the input on the left is reformatted into the output on the right, where newlines are ignored.
     
    796796This semantics is basically a tail-call optimization, which compilers already perform.
    797797The example shows the assembly code to undo the generator's entry code before the direct jump.
    798 This assembly code depends on what entry code is generated, specifically if there are local variables and the level of optimization.
     798This assembly code depends on what entry code is generated, specifically if there are local variables, and the level of optimization.
    799799To provide this new calling convention requires a mechanism built into the compiler, which is beyond the scope of \CFA at this time.
    800800Nevertheless, it is possible to hand generate any symmetric generators for proof of concept and performance testing.
    801 A compiler could also eliminate other artifacts in the generator simulation to further increase performance.
     801A compiler could also eliminate other artifacts in the generator simulation to further increase performance, \eg LLVM has various coroutine support~\cite{CoroutineTS}, and \CFA can leverage this support should it fork @clang@.
    802802
    803803\begin{figure}
     
    12131213Hence, a compromise solution is necessary that works for asymmetric (acyclic) and symmetric (cyclic) coroutines.
    12141214
    1215 Our solution for coroutine termination works well for the most common asymmetric and symmetric coroutine usage-patterns.
     1215Our solution is to context switch back to the first resumer (starter) once the coroutine ends.
     1216This semantics works well for the most common asymmetric and symmetric coroutine usage-patterns.
    12161217For asymmetric coroutines, it is common for the first resumer (starter) coroutine to be the only resumer.
    12171218All previous generators converted to coroutines have this property.
     
    12451246
    12461247
    1247 \subsection{(Generator) Coroutine Implementation}
     1248\subsection{Generator / Coroutine Implementation}
    12481249
    12491250A significant implementation challenge for generators/coroutines (and threads in Section~\ref{s:threads}) is adding extra fields to the custom types and related functions, \eg inserting code after/before the coroutine constructor/destructor and @main@ to create/initialize/de-initialize/destroy any extra fields, \eg stack.
     
    12541255class myCoroutine inherits baseCoroutine { ... }
    12551256\end{cfa}
    1256 The problem is that the programming language and its tool chain, \eg debugger, @valgrind@, need to understand @baseCoroutine@ because it infers special property, so type @baseCoroutine@ becomes a de facto keyword and all types inheriting from it are implicitly custom types.
    1257 As well, some special properties are not handled by existing language semantics, \eg the execution of constructors/destructors is in the wrong order to implicitly start threads because the thread must start \emph{after} all constructors as it relies on a completely initialized object, but the inherited constructor runs \emph{before} the derived.
     1257% The problem is that the programming language and its tool chain, \eg debugger, @valgrind@, need to understand @baseCoroutine@ because it infers special property, so type @baseCoroutine@ becomes a de facto keyword and all types inheriting from it are implicitly custom types.
     1258The problem is that some special properties are not handled by existing language semantics, \eg the execution of constructors/destructors is in the wrong order to implicitly start threads because the thread must start \emph{after} all constructors as it relies on a completely initialized object, but the inherited constructor runs \emph{before} the derived.
    12581259Alternatives, such as explicitly starting threads as in Java, are repetitive and forgetting to call start is a common source of errors.
    12591260An alternative is composition:
     
    12671268However, there is nothing preventing wrong placement or multiple declarations.
    12681269
    1269 \CFA custom types make any special properties explicit to the language and its tool chain, \eg the language code-generator knows where to inject code and when it is unsafe to perform certain optimizations, and IDEs using simple parsing can find and manipulate types with special properties.
     1270\CFA custom types make any special properties explicit to the language and its tool chain, \eg the language code-generator knows where to inject code
     1271% and when it is unsafe to perform certain optimizations,
     1272and IDEs using simple parsing can find and manipulate types with special properties.
    12701273The downside of this approach is that it makes custom types a special case in the language.
    12711274Users wanting to extend custom types or build their own can only do so in ways offered by the language.
     
    12821285\end{cfa}
    12831286Note, copying generators/coroutines/threads is not meaningful.
    1284 For example, a coroutine retains its last resumer and suspends back to it;
    1285 having a copy also suspend back to the same resumer is undefined semantics.
     1287For example, both the resumer and suspender descriptors can have bi-directional pointers;
     1288copying these coroutines does not update the internal pointers so behaviour of both copies would be difficult to understand.
    12861289Furthermore, two coroutines cannot logically execute on the same stack.
    12871290A deep coroutine copy, which copies the stack, is also meaningless in an unmanaged language (no garbage collection), like C, because the stack may contain pointers to object within it that require updating for the copy.
    12881291The \CFA @dtype@ property provides no \emph{implicit} copying operations and the @is_coroutine@ trait provides no \emph{explicit} copying operations, so all coroutines must be passed by reference (pointer).
    1289 The function definitions ensures there is a statically-typed @main@ function that is the starting point (first stack frame) of a coroutine, and a mechanism to get (read) the currently executing coroutine handle.
     1292The function definitions ensures there is a statically-typed @main@ function that is the starting point (first stack frame) of a coroutine, and a mechanism to get (read) the coroutine descriptor from its handle.
    12901293The @main@ function has no return value or additional parameters because the coroutine type allows an arbitrary number of interface functions with corresponding arbitrary typed input/output values versus fixed ones.
    12911294The advantage of this approach is that users can easily create different types of coroutines, \eg changing the memory layout of a coroutine is trivial when implementing the @get_coroutine@ function, and possibly redefining \textsf{suspend} and @resume@.
     
    14931496\end{tabular}
    14941497\end{cquote}
    1495 Like coroutines, the @dtype@ property prevents \emph{implicit} copy operations and the @is_coroutine@ trait provides no \emph{explicit} copy operations, so threads must be passed by reference (pointer).
    1496 Similarly, the function definitions ensures there is a statically-typed @main@ function that is the thread starting point (first stack frame), a mechanism to get (read) the currently executing thread handle, and a special destructor to prevent deallocation while the thread is executing.
     1498Like coroutines, the @dtype@ property prevents \emph{implicit} copy operations and the @is_thread@ trait provides no \emph{explicit} copy operations, so threads must be passed by reference (pointer).
     1499Similarly, the function definitions ensures there is a statically-typed @main@ function that is the thread starting point (first stack frame), a mechanism to get (read) the thread descriptor from its handle, and a special destructor to prevent deallocation while the thread is executing.
    14971500(The qualifier @mutex@ for the destructor parameter is discussed in Section~\ref{s:Monitor}.)
    14981501The difference between the coroutine and thread is that a coroutine borrows a thread from its caller, so the first thread resuming a coroutine creates the coroutine's stack and starts running the coroutine main on the stack;
     
    16171620% Copying a lock is insecure because it is possible to copy an open lock and then use the open copy when the original lock is closed to simultaneously access the shared data.
    16181621% Copying a monitor is secure because both the lock and shared data are copies, but copying the shared data is meaningless because it no longer represents a unique entity.
    1619 Similarly, the function definitions ensures there is a mechanism to get (read) the currently executing monitor handle, and a special destructor to prevent deallocation if a thread using the shared data.
     1622Similarly, the function definitions ensures there is a mechanism to get (read) the monitor descriptor from its handle, and a special destructor to prevent deallocation if a thread using the shared data.
    16201623The custom monitor type also inserts any locks needed to implement the mutual exclusion semantics.
    16211624
     
    16561659called \newterm{bulk acquire}.
    16571660\CFA guarantees acquisition order is consistent across calls to @mutex@ functions using the same monitors as arguments, so acquiring multiple monitors is safe from deadlock.
    1658 Figure~\ref{f:BankTransfer} shows a trivial solution to the bank transfer problem, where two resources must be locked simultaneously, using \CFA monitors with implicit locking and \CC with explicit locking.
     1661Figure~\ref{f:BankTransfer} shows a trivial solution to the bank transfer problem~\cite{BankTransfer}, where two resources must be locked simultaneously, using \CFA monitors with implicit locking and \CC with explicit locking.
    16591662A \CFA programmer only has to manage when to acquire mutual exclusion;
    16601663a \CC programmer must select the correct lock and acquisition mechanism from a panoply of locking options.
     
    18001803Figure~\ref{f:MonitorScheduling} shows general internal/external scheduling (for the bounded-buffer example in Figure~\ref{f:InternalExternalScheduling}).
    18011804External calling threads block on the calling queue, if the monitor is occupied, otherwise they enter in FIFO order.
    1802 Internal threads block on condition queues via @wait@ and they reenter from the condition in FIFO order, or they block on urgent via @signal_block@ or @waitfor@ and reenter implicit when the monitor becomes empty, \ie, the thread in the monitor exits or waits.
     1805Internal threads block on condition queues via @wait@ and reenter from the condition in FIFO order.
     1806Alternatively, internal threads block on urgent from the @signal_block@ or @waitfor@, and reenter implicitly when the monitor becomes empty, \ie, the thread in the monitor exits or waits.
    18031807
    18041808There are three signalling mechanisms to unblock waiting threads to enter the monitor.
    1805 Note, signalling cannot have the signaller and signalled thread in the monitor simultaneously because of the mutual exclusion so only one can proceed.
     1809Note, signalling cannot have the signaller and signalled thread in the monitor simultaneously because of the mutual exclusion, so either the signaller or signallee can proceed.
    18061810For internal scheduling, threads are unblocked from condition queues using @signal@, where the signallee is moved to urgent and the signaller continues (solid line).
    18071811Multiple signals move multiple signallees to urgent, until the condition is empty.
     
    18431847It is common to declare condition variables as monitor fields to prevent shared access, hence no locking is required for access as the conditions are protected by the monitor lock.
    18441848In \CFA, a condition variable can be created/stored independently.
    1845 To still prevent expensive locking on access, a condition variable is tied to a \emph{group} of monitors on first use, called \newterm{branding}, resulting in a low-cost boolen test to detect sharing from other monitors.
     1849% To still prevent expensive locking on access, a condition variable is tied to a \emph{group} of monitors on first use, called \newterm{branding}, resulting in a low-cost boolean test to detect sharing from other monitors.
    18461850
    18471851% Signalling semantics cannot have the signaller and signalled thread in the monitor simultaneously, which means:
     
    18521856% The signalling thread continues and the signalled thread is marked for urgent unblocking at the next scheduling point (exit/wait).
    18531857% \item
    1854 % The signalling thread blocks but is marked for urgrent unblocking at the next scheduling point and the signalled thread continues.
     1858% The signalling thread blocks but is marked for urgent unblocking at the next scheduling point and the signalled thread continues.
    18551859% \end{enumerate}
    18561860% The first approach is too restrictive, as it precludes solving a reasonable class of problems, \eg dating service (see Figure~\ref{f:DatingService}).
     
    19611965External scheduling is controlled by the @waitfor@ statement, which atomically blocks the calling thread, releases the monitor lock, and restricts the function calls that can next acquire mutual exclusion.
    19621966If the buffer is full, only calls to @remove@ can acquire the buffer, and if the buffer is empty, only calls to @insert@ can acquire the buffer.
    1963 Calls threads to functions that are currently excluded block outside of (external to) the monitor on the calling queue, versus blocking on condition queues inside of (internal to) the monitor.
     1967Threads calling excluded functions block outside of (external to) the monitor on the calling queue, versus blocking on condition queues inside of (internal to) the monitor.
    19641968Figure~\ref{f:RWExt} shows a readers/writer lock written using external scheduling, where a waiting reader detects a writer using the resource and restricts further calls until the writer exits by calling @EndWrite@.
    19651969The writer does a similar action for each reader or writer using the resource.
     
    20762080For @wait( e )@, the default semantics is to atomically block the signaller and release all acquired mutex parameters, \ie @wait( e, m1, m2 )@.
    20772081To override the implicit multi-monitor wait, specific mutex parameter(s) can be specified, \eg @wait( e, m1 )@.
    2078 Wait statically verifies the released monitors are the acquired mutex-parameters so unconditional release is safe.
     2082Wait cannot statically verifies the released monitors are the acquired mutex-parameters without disallowing separately compiled helper functions calling @wait@.
    20792083While \CC supports bulk locking, @wait@ only accepts a single lock for a condition variable, so bulk locking with condition variables is asymmetric.
    20802084Finally, a signaller,
     
    20882092Similarly, for @waitfor( rtn )@, the default semantics is to atomically block the acceptor and release all acquired mutex parameters, \ie @waitfor( rtn, m1, m2 )@.
    20892093To override the implicit multi-monitor wait, specific mutex parameter(s) can be specified, \eg @waitfor( rtn, m1 )@.
    2090 @waitfor@ statically verifies the released monitors are the same as the acquired mutex-parameters of the given function or function pointer.
    2091 To statically verify the released monitors match with the accepted function's mutex parameters, the function (pointer) prototype must be accessible.
     2094@waitfor@ does statically verify the monitor types passed are the same as the acquired mutex-parameters of the given function or function pointer, hence the function (pointer) prototype must be accessible.
    20922095% When an overloaded function appears in an @waitfor@ statement, calls to any function with that name are accepted.
    20932096% The rationale is that members with the same name should perform a similar function, and therefore, all should be eligible to accept a call.
     
    21482151The right example accepts either @mem1@ or @mem2@ if @C1@ and @C2@ are true.
    21492152
    2150 An interesting use of @waitfor@ is accepting the @mutex@ destructor to know when an object is deallocated.
    2151 \begin{cfa}
    2152 void insert( Buffer(T) & mutex buffer, T elem ) with( buffer ) {
    2153         if ( count == 10 )
    2154                 waitfor( remove, buffer ) {
    2155                         // insert elem into buffer
    2156                 } or `waitfor( ^?{}, buffer )` throw insertFail;
    2157 }
    2158 \end{cfa}
    2159 When the buffer is deallocated, the current waiter is unblocked and informed, so it can perform an appropriate action.
    2160 However, the basic @waitfor@ semantics do not support this functionality, since using an object after its destructor is called is undefined.
    2161 Therefore, to make this useful capability work, the semantics for accepting the destructor is the same as @signal@, \ie the call to the destructor is placed on the urgent queue and the acceptor continues execution, which throws an exception to the acceptor and then the caller is unblocked from the urgent queue to deallocate the object.
    2162 Accepting the destructor is the idiomatic way to terminate a thread in \CFA.
     2153An interesting use of @waitfor@ is accepting the @mutex@ destructor to know when an object is deallocated, \eg assume the bounded buffer is restructred from a monitor to a thread with the following @main@.
     2154\begin{cfa}
     2155void main( Buffer(T) & buffer ) with(buffer) {
     2156        for () {
     2157                `waitfor( ^?{}, buffer )` break;
     2158                or when ( count != 20 ) waitfor( insert, buffer ) { ... }
     2159                or when ( count != 0 ) waitfor( remove, buffer ) { ... }
     2160        }
     2161        // clean up
     2162}
     2163\end{cfa}
     2164When the program main deallocates the buffer, it first calls the buffer's destructor, which is accepted, the destructor runs, and the buffer is deallocated.
     2165However, the buffer thread cannot continue after the destructor call because the object is gone;
     2166hence, clean up in @main@ cannot occur, which means destructors for local objects are not run.
     2167To make this useful capability work, the semantics for accepting the destructor is the same as @signal@, \ie the destructor call is placed on urgent and the acceptor continues execution, which ends the loop, cleans up, and the thread terminates.
     2168Then, the destructor caller unblocks from urgent to deallocate the object.
     2169Accepting the destructor is the idiomatic way in \CFA to terminate a thread performing direct communication.
    21632170
    21642171
     
    23572364
    23582365struct Msg { int i, j; };
    2359 thread Gortn { int i;  float f;  Msg m; };
    2360 void mem1( Gortn & mutex gortn, int i ) { gortn.i = i; }
    2361 void mem2( Gortn & mutex gortn, float f ) { gortn.f = f; }
    2362 void mem3( Gortn & mutex gortn, Msg m ) { gortn.m = m; }
    2363 void ^?{}( Gortn & mutex ) {}
    2364 
    2365 void main( Gortn & gortn ) with( gortn ) {  // thread starts
     2366thread GoRtn { int i;  float f;  Msg m; };
     2367void mem1( GoRtn & mutex gortn, int i ) { gortn.i = i; }
     2368void mem2( GoRtn & mutex gortn, float f ) { gortn.f = f; }
     2369void mem3( GoRtn & mutex gortn, Msg m ) { gortn.m = m; }
     2370void ^?{}( GoRtn & mutex ) {}
     2371
     2372void main( GoRtn & gortn ) with( gortn ) {  // thread starts
    23662373
    23672374        for () {
     
    23762383}
    23772384int main() {
    2378         Gortn gortn; $\C[2.0in]{// start thread}$
     2385        GoRtn gortn; $\C[2.0in]{// start thread}$
    23792386        `mem1( gortn, 0 );` $\C{// different calls}\CRT$
    23802387        `mem2( gortn, 2.5 );`
     
    25342541% However, preemption is necessary for fairness and to reduce tail-latency.
    25352542% For concurrency that relies on spinning, if all cores spin the system is livelocked, whereas preemption breaks the livelock.
    2536 %
    2537 %
    2538 % \subsection{Thread Pools}
    2539 %
    2540 % In contrast to direct threading is indirect \newterm{thread pools}, \eg Java @executor@, where small jobs (work units) are inserted into a work pool for execution.
    2541 % If the jobs are dependent, \ie interact, there is an implicit/explicit dependency graph that ties them together.
    2542 % While removing direct concurrency, and hence the amount of context switching, thread pools significantly limit the interaction that can occur among jobs.
    2543 % Indeed, jobs should not block because that also blocks the underlying thread, which effectively means the CPU utilization, and therefore throughput, suffers.
    2544 % While it is possible to tune the thread pool with sufficient threads, it becomes difficult to obtain high throughput and good core utilization as job interaction increases.
    2545 % As well, concurrency errors return, which threads pools are suppose to mitigate.
     2543
     2544
     2545\begin{comment}
     2546\subsection{Thread Pools}
     2547
     2548In contrast to direct threading is indirect \newterm{thread pools}, \eg Java @executor@, where small jobs (work units) are inserted into a work pool for execution.
     2549If the jobs are dependent, \ie interact, there is an implicit/explicit dependency graph that ties them together.
     2550While removing direct concurrency, and hence the amount of context switching, thread pools significantly limit the interaction that can occur among jobs.
     2551Indeed, jobs should not block because that also blocks the underlying thread, which effectively means the CPU utilization, and therefore throughput, suffers.
     2552While it is possible to tune the thread pool with sufficient threads, it becomes difficult to obtain high throughput and good core utilization as job interaction increases.
     2553As well, concurrency errors return, which threads pools are suppose to mitigate.
     2554
     2555\begin{figure}
     2556\centering
     2557\begin{tabular}{@{}l|l@{}}
     2558\begin{cfa}
     2559struct Adder {
     2560    int * row, cols;
     2561};
     2562int operator()() {
     2563        subtotal = 0;
     2564        for ( int c = 0; c < cols; c += 1 )
     2565                subtotal += row[c];
     2566        return subtotal;
     2567}
     2568void ?{}( Adder * adder, int row[$\,$], int cols, int & subtotal ) {
     2569        adder.[rows, cols, subtotal] = [rows, cols, subtotal];
     2570}
     2571
     2572
     2573
     2574
     2575\end{cfa}
     2576&
     2577\begin{cfa}
     2578int main() {
     2579        const int rows = 10, cols = 10;
     2580        int matrix[rows][cols], subtotals[rows], total = 0;
     2581        // read matrix
     2582        Executor executor( 4 ); // kernel threads
     2583        Adder * adders[rows];
     2584        for ( r; rows ) { // send off work for executor
     2585                adders[r] = new( matrix[r], cols, &subtotal[r] );
     2586                executor.send( *adders[r] );
     2587        }
     2588        for ( r; rows ) {       // wait for results
     2589                delete( adders[r] );
     2590                total += subtotals[r];
     2591        }
     2592        sout | total;
     2593}
     2594\end{cfa}
     2595\end{tabular}
     2596\caption{Executor}
     2597\end{figure}
     2598\end{comment}
    25462599
    25472600
     
    25672620The purpose of a cluster is to control the amount of parallelism that is possible among threads, plus scheduling and other execution defaults.
    25682621The default cluster-scheduler is single-queue multi-server, which provides automatic load-balancing of threads on processors.
    2569 However, the scheduler is pluggable, supporting alternative schedulers, such as multi-queue multi-server, with work-stealing/sharing across the virtual processors.
     2622However, the design allows changing the scheduler, \eg multi-queue multi-server with work-stealing/sharing across the virtual processors.
    25702623If several clusters exist, both threads and virtual processors, can be explicitly migrated from one cluster to another.
    25712624No automatic load balancing among clusters is performed by \CFA.
     
    25742627The user cluster is created to contain the application user-threads.
    25752628Having all threads execute on the one cluster often maximizes utilization of processors, which minimizes runtime.
    2576 However, because of limitations of the underlying operating system, heterogeneous hardware, or scheduling requirements (real-time), multiple clusters are sometimes necessary.
     2629However, because of limitations of scheduling requirements (real-time), NUMA architecture, heterogeneous hardware, or issues with the underlying operating system, multiple clusters are sometimes necessary.
    25772630
    25782631
     
    26182671\subsection{Preemption}
    26192672
    2620 Nondeterministic preemption provides fairness from long running threads, and forces concurrent programmers to write more robust programs, rather than relying on section of code between cooperative scheduling to be atomic.
    2621 A separate reason for not supporting preemption is that it significantly complicates the runtime system.
     2673Nondeterministic preemption provides fairness from long running threads, and forces concurrent programmers to write more robust programs, rather than relying on code between cooperative scheduling to be atomic.
     2674This atomic reliance can fail on multi-core machines, because execution across cores is nondeterministic.
     2675A different reason for not supporting preemption is that it significantly complicates the runtime system, \eg Microsoft runtime does not support interrupts and on Linux systems, interrupts are complex (see below).
    26222676Preemption is normally handled by setting a count-down timer on each virtual processor.
    26232677When the timer expires, an interrupt is delivered, and the interrupt handler resets the count-down timer, and if the virtual processor is executing in user code, the signal handler performs a user-level context-switch, or if executing in the language runtime-kernel, the preemption is ignored or rolled forward to the point where the runtime kernel context switches back to user code.
     
    26282682Because preemption frequency is usually long (1 millisecond) performance cost is negligible.
    26292683
    2630 However, on current Linux systems:
     2684Linux switched a decade ago from specific to arbitrary process signal-delivery for applications with multiple kernel threads.
    26312685\begin{cquote}
    26322686A process-directed signal may be delivered to any one of the threads that does not currently have the signal blocked.
     
    26342688SIGNAL(7) - Linux Programmer's Manual
    26352689\end{cquote}
    2636 Hence, the timer-expiry signal, which is generated \emph{externally} by the Linux kernel to the Linux process, is delivered to any of its Linux subprocesses (kernel threads).
    2637 To ensure each virtual processor receives its own preemption signals, a discrete-event simulation is run on a special virtual processor, and only it sets and receives timer events.
     2690Hence, the timer-expiry signal, which is generated \emph{externally} by the Linux kernel to an application, is delivered to any of its Linux subprocesses (kernel threads).
     2691To ensure each virtual processor receives a preemption signal, a discrete-event simulation is run on a special virtual processor, and only it sets and receives timer events.
    26382692Virtual processors register an expiration time with the discrete-event simulator, which is inserted in sorted order.
    26392693The simulation sets the count-down timer to the value at the head of the event list, and when the timer expires, all events less than or equal to the current time are processed.
     
    26522706
    26532707To verify the implementation of the \CFA runtime, a series of microbenchmarks are performed comparing \CFA with Java OpenJDK-9, Go 1.9.2 and \uC 7.0.0.
    2654 The benchmark computer is an AMD Opteron\texttrademark\ 6380 NUMA 64-core, 8 socket, 2.5 GHz processor, running Ubuntu 16.04.3 LTS and \uC and \CFA are compiled with gcc 6.3.
     2708The benchmark computer is an AMD Opteron\texttrademark\ 6380 NUMA 64-core, 8 socket, 2.5 GHz processor, running Ubuntu 16.04.6 LTS, and \uC/\CFA are compiled with gcc 6.5.
    26552709
    26562710\begin{comment}
     
    27072761\lstset{language=CFA,moredelim=**[is][\color{red}]{@}{@},deletedelim=**[is][]{`}{`}}
    27082762\begin{cfa}
    2709 thread MyThread {};
    2710 void main( MyThread & ) {}
     2763@thread@ MyThread {};
     2764void @main@( MyThread & ) {}
    27112765int main() {
    27122766        BENCH( for ( N ) { @MyThread m;@ } )
     
    27502804\lstset{language=CFA,moredelim=**[is][\color{red}]{@}{@},deletedelim=**[is][]{`}{`}}
    27512805\begin{cfa}[aboveskip=0pt,belowskip=0pt]
    2752 coroutine C {} c;
     2806@coroutine@ C {} c;
    27532807void main( C & ) { for ( ;; ) { @suspend;@ } }
    27542808int main() { // coroutine test
     
    27712825\begin{tabular}{@{}r*{3}{D{.}{.}{3.2}}@{}}
    27722826\multicolumn{1}{@{}c}{} & \multicolumn{1}{c}{Median} &\multicolumn{1}{c}{Average} & \multicolumn{1}{c@{}}{Std Dev} \\
    2773 Kernel Thread   & 333.5 & 332.96        & 4.1   \\
     2827C function              & 2                     & 2             & 0             \\
     2828\CFA generator  & 2                     & 2             & 0             \\
    27742829\CFA Coroutine  & 49    & 48.68         & 0.47  \\
    27752830\CFA Thread             & 105   & 105.57        & 1.37  \\
     
    27772832\uC Thread              & 100   & 99.29         & 0.96  \\
    27782833Goroutine               & 145   & 147.25        & 4.15  \\
    2779 Java Thread             & 373.5 & 375.14        & 8.72
     2834Java Thread             & 373.5 & 375.14        & 8.72  \\
     2835Pthreads Thread & 333.5 & 332.96        & 4.1
    27802836\end{tabular}
    27812837\end{multicols}
     
    27932849\lstset{language=CFA,moredelim=**[is][\color{red}]{@}{@},deletedelim=**[is][]{`}{`}}
    27942850\begin{cfa}
    2795 monitor M {} m1/*, m2, m3, m4*/;
     2851@monitor@ M {} m1/*, m2, m3, m4*/;
    27962852void __attribute__((noinline))
    2797 do_call( M & mutex m/*, m2, m3, m4*/ ) {}
     2853do_call( M & @mutex m/*, m2, m3, m4*/@ ) {}
    27982854int main() {
    27992855        BENCH(
    2800                 for( N ) @do_call( m1/*, m2, m3, m4*/ );@
     2856                for( N ) do_call( m1/*, m2, m3, m4*/ );
    28012857        )
    28022858        sout | result`ns;
     
    28132869\begin{tabular}{@{}r*{3}{D{.}{.}{3.2}}@{}}
    28142870\multicolumn{1}{@{}c}{} & \multicolumn{1}{c}{Median} &\multicolumn{1}{c}{Average} & \multicolumn{1}{c@{}}{Std Dev} \\
    2815 C function                                              & 2                     & 2             & 0             \\
    2816 FetchAdd + FetchSub                             & 26            & 26    & 0             \\
     2871test and test-and-test lock             & 26            & 26    & 0             \\
    28172872Pthreads Mutex Lock                             & 31            & 31.71 & 0.97  \\
    28182873\uC @monitor@ member rtn.               & 31            & 31    & 0             \\
     
    28202875\CFA @mutex@ function, 2 arg.   & 84            & 85.36 & 1.99  \\
    28212876\CFA @mutex@ function, 4 arg.   & 158           & 161   & 4.22  \\
    2822 Java synchronized function              & 27.5          & 29.79 & 2.93
     2877Java synchronized method                & 27.5          & 29.79 & 2.93
    28232878\end{tabular}
    28242879\end{multicols}
     
    28362891\begin{cfa}
    28372892volatile int go = 0;
    2838 monitor M { condition c; } m;
     2893@monitor@ M { @condition c;@ } m;
    28392894void __attribute__((noinline))
    2840 do_call( M & mutex a1 ) { @signal( c );@ }
     2895do_call( M & @mutex@ a1 ) { @signal( c );@ }
    28412896thread T {};
    28422897void main( T & this ) {
     
    28692924\multicolumn{1}{@{}c}{} & \multicolumn{1}{c}{Median} & \multicolumn{1}{c}{Average} & \multicolumn{1}{c@{}}{Std Dev} \\
    28702925Pthreads Cond. Variable         & 6005          & 5681.43       & 835.45        \\
    2871 \uC @signal@                            & 324           & 325.54        & 3,02          \\
     2926\uC @signal@                            & 324           & 325.54        & 3.02          \\
    28722927\CFA @signal@, 1 @monitor@      & 368.5         & 370.61        & 4.77          \\
    28732928\CFA @signal@, 2 @monitor@      & 467           & 470.5         & 6.79          \\
     
    28892944\begin{cfa}
    28902945volatile int go = 0;
    2891 monitor M {} m;
     2946@monitor@ M {} m;
    28922947thread T {};
    28932948void __attribute__((noinline))
    2894 do_call( M & mutex ) {}
     2949do_call( M & @mutex@ ) {}
    28952950void main( T & ) {
    28962951        while ( go == 0 ) { yield(); }
    2897         while ( go == 1 ) { @do_call( m );@ }
     2952        while ( go == 1 ) { do_call( m ); }
    28982953}
    28992954int __attribute__((noinline))
    2900 do_wait( M & mutex m ) {
     2955do_wait( M & @mutex@ m ) {
    29012956        go = 1; // continue other thread
    29022957        BENCH( for ( N ) { @waitfor( do_call, m );@ } )
  • doc/papers/concurrency/annex/local.bib

    r18e683b rc1ea11b  
    6666}
    6767
    68 @article{BankTransfer,
     68@misc{BankTransfer,
    6969        key     = {Bank Transfer},
    7070        keywords        = {Bank Transfer},
    7171        title   = {Bank Account Transfer Problem},
    72         publisher       = {Wiki Wiki Web},
    73         address = {http://wiki.c2.com},
     72        howpublished    = {Wiki Wiki Web, \url{http://wiki.c2.com/?BankAccountTransferProblem}},
    7473        year            = 2010
    7574}
  • doc/papers/concurrency/examples/Fib.cfa

    r18e683b rc1ea11b  
    1313}
    1414
    15 #define FibCtor { 0, 1 }
    16 typedef struct { int fn, fn1; } Fib;
    17 int fib_state( Fib & f ) with( f ) {
    18         int fn0 = fn1 + fn2;  fn2 = fn1;  fn = fn0;
    19         return fn1;
     15#define FibCtor { 1, 0 }
     16typedef struct { int fn1, fn; } Fib;
     17int fib_state( Fib & f ) with(f) {
     18        int ret = fn; fn = fn1; fn1 = fn + ret;
     19        return ret;
    2020}
    2121
     
    3232coroutine Fib2 { int fn; };                                             // used for communication
    3333void main( Fib2 & fib ) with( fib ) {                   // called on first resume
    34         int fn1 = 1, fn2 = 0;                                           // precompute first two states
     34        int fn1;                                                                        // precompute first two states
     35        [fn1, fn] = [1, 0];
    3536        for () {
    36                 fn = fn1 + fn2;  fn2 = fn1;  fn1 = fn;  // general case
    3737                suspend();                                                              // restart last resume
     38                [fn1, fn] = [fn, fn + fn1];
    3839        }
    3940}
    40 int ?()( Fib2 & fib ) with( fib ) {
     41int ?()( Fib2 & fib ) {                                                 // function-call interface
    4142        return resume( fib ).fn;                                        // restart last suspend
    4243}
    43 int ?()( Fib2 & fib, int N ) with( fib ) {
    44         for ( N - 1 ) fib();
     44int ?()( Fib2 & fib, int N ) {                                  // skip N values
     45        for ( N - 1 ) fib();                                            // use function-call interface
    4546        return fib();
    4647}
    47 double ?()( Fib2 & fib ) with( fib ) {
    48         return (int)(fib()) / 3.14159;                                          // restart last suspend
     48double ?()( Fib2 & fib ) {                                              // different return type
     49        return (int)(fib()) / 3.14159;                          // cast prevents recursive call
    4950}
    5051
  • doc/user/user.tex

    r18e683b rc1ea11b  
    1111%% Created On       : Wed Apr  6 14:53:29 2016
    1212%% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Sun May  5 18:24:50 2019
    14 %% Update Count     : 3489
     13%% Last Modified On : Sat Jun 15 16:29:45 2019
     14%% Update Count     : 3847
    1515%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1616
     
    254254\begin{lstlisting}
    255255®forall( otype T )® T identity( T val ) { return val; }
    256 int forty_two = identity( 42 );                         §\C{// T is bound to int, forty\_two == 42}§
     256int forty_two = identity( 42 ); §\C{// T is bound to int, forty\_two == 42}§
    257257\end{lstlisting}
    258258% extending the C type system with parametric polymorphism and overloading, as opposed to the \Index*[C++]{\CC{}} approach of object-oriented extensions.
     
    282282
    283283double key = 5.0, vals[10] = { /* 10 sorted floating values */ };
    284 double * val = (double *)bsearch( &key, vals, 10, sizeof(vals[0]), comp );      §\C{// search sorted array}§
     284double * val = (double *)bsearch( &key, vals, 10, sizeof(vals[0]), comp ); §\C{// search sorted array}§
    285285\end{lstlisting}
    286286which can be augmented simply with a polymorphic, type-safe, \CFA-overloaded wrappers:
     
    291291
    292292forall( otype T | { int ?<?( T, T ); } ) unsigned int bsearch( T key, const T * arr, size_t size ) {
    293         T * result = bsearch( key, arr, size ); §\C{// call first version}§
    294         return result ? result - arr : size; }  §\C{// pointer subtraction includes sizeof(T)}§
    295 
    296 double * val = bsearch( 5.0, vals, 10 );        §\C{// selection based on return type}§
     293        T * result = bsearch( key, arr, size ); §\C{// call first version}§
     294        return result ? result - arr : size; } §\C{// pointer subtraction includes sizeof(T)}§
     295
     296double * val = bsearch( 5.0, vals, 10 ); §\C{// selection based on return type}§
    297297int posn = bsearch( 5.0, vals, 10 );
    298298\end{lstlisting}
     
    306306\begin{lstlisting}
    307307forall( dtype T | sized(T) ) T * malloc( void ) { return (T *)malloc( sizeof(T) ); }
    308 int * ip = malloc();                                            §\C{// select type and size from left-hand side}§
     308int * ip = malloc(); §\C{// select type and size from left-hand side}§
    309309double * dp = malloc();
    310310struct S {...} * sp = malloc();
     
    318318\begin{cfa}
    319319char ®abs®( char );
    320 extern "C" { int ®abs®( int ); }                        §\C{// use default C routine for int}§
     320extern "C" { int ®abs®( int ); } §\C{// use default C routine for int}§
    321321long int ®abs®( long int );
    322322long long int ®abs®( long long int );
     
    426426\begin{cfa}
    427427#ifndef __CFORALL__
    428 #include <stdio.h>§\indexc{stdio.h}§            §\C{// C header file}§
     428#include <stdio.h>§\indexc{stdio.h}§ §\C{// C header file}§
    429429#else
    430 #include <fstream>§\indexc{fstream}§            §\C{// \CFA header file}§
     430#include <fstream>§\indexc{fstream}§ §\C{// \CFA header file}§
    431431#endif
    432432\end{cfa}
     
    512512Keyword clashes are accommodated by syntactic transformations using the \CFA backquote escape-mechanism:
    513513\begin{cfa}
    514 int ®`®otype®`® = 3;                                            §\C{// make keyword an identifier}§
     514int ®`®otype®`® = 3; §\C{// make keyword an identifier}§
    515515double ®`®forall®`® = 3.5;
    516516\end{cfa}
     
    523523\begin{cfa}
    524524// include file uses the CFA keyword "with".
    525 #if ! defined( with )                                           §\C{// nesting ?}§
    526 #define with ®`®with®`®                                         §\C{// make keyword an identifier}§
     525#if ! defined( with ) §\C{// nesting ?}§
     526#define with ®`®with®`® §\C{// make keyword an identifier}§
    527527#define __CFA_BFD_H__
    528528#endif
    529529
    530 ®#include_next <bfdlink.h>                      §\C{// must have internal check for multiple expansion}§
     530®#include_next <bfdlink.h> §\C{// must have internal check for multiple expansion}§
    531531®
    532532#if defined( with ) && defined( __CFA_BFD_H__ ) §\C{// reset only if set}§
     
    544544Numeric constants are extended to allow \Index{underscore}s\index{constant!underscore}, \eg:
    545545\begin{cfa}
    546 2®_®147®_®483®_®648;                                            §\C{// decimal constant}§
    547 56®_®ul;                                                                        §\C{// decimal unsigned long constant}§
    548 0®_®377;                                                                        §\C{// octal constant}§
    549 0x®_®ff®_®ff;                                                           §\C{// hexadecimal constant}§
    550 0x®_®ef3d®_®aa5c;                                                       §\C{// hexadecimal constant}§
    551 3.141®_®592®_®654;                                                      §\C{// floating constant}§
    552 10®_®e®_®+1®_®00;                                                       §\C{// floating constant}§
    553 0x®_®ff®_®ff®_®p®_®3;                                           §\C{// hexadecimal floating}§
    554 0x®_®1.ffff®_®ffff®_®p®_®128®_®l;                       §\C{// hexadecimal floating long constant}§
    555 L®_®§"\texttt{\textbackslash{x}}§®_®§\texttt{ff}§®_®§\texttt{ee}"§;     §\C{// wide character constant}§
     5462®_®147®_®483®_®648; §\C{// decimal constant}§
     54756®_®ul; §\C{// decimal unsigned long constant}§
     5480®_®377; §\C{// octal constant}§
     5490x®_®ff®_®ff; §\C{// hexadecimal constant}§
     5500x®_®ef3d®_®aa5c; §\C{// hexadecimal constant}§
     5513.141®_®592®_®654; §\C{// floating constant}§
     55210®_®e®_®+1®_®00; §\C{// floating constant}§
     5530x®_®ff®_®ff®_®p®_®3; §\C{// hexadecimal floating}§
     5540x®_®1.ffff®_®ffff®_®p®_®128®_®l; §\C{// hexadecimal floating long constant}§
     555L®_®§"\texttt{\textbackslash{x}}§®_®§\texttt{ff}§®_®§\texttt{ee}"§; §\C{// wide character constant}§
    556556\end{cfa}
    557557The rules for placement of underscores are:
     
    612612(Does not make sense for ©do©-©while©.)
    613613\begin{cfa}
    614 if ( ®int x = f()® ) ...                                        §\C{// x != 0}§
    615 if ( ®int x = f(), y = g()® ) ...                       §\C{// x != 0 \&\& y != 0}§
    616 if ( ®int x = f(), y = g(); x < y® ) ...        §\C{// relational expression}§
     614if ( ®int x = f()® ) ... §\C{// x != 0}§
     615if ( ®int x = f(), y = g()® ) ... §\C{// x != 0 \&\& y != 0}§
     616if ( ®int x = f(), y = g(); x < y® ) ... §\C{// relational expression}§
    617617if ( ®struct S { int i; } x = { f() }; x.i < 4® ) §\C{// relational expression}§
    618618
    619 while ( ®int x = f()® ) ...                                     §\C{// x != 0}§
    620 while ( ®int x = f(), y = g()® ) ...            §\C{// x != 0 \&\& y != 0}§
     619while ( ®int x = f()® ) ... §\C{// x != 0}§
     620while ( ®int x = f(), y = g()® ) ... §\C{// x != 0 \&\& y != 0}§
    621621while ( ®int x = f(), y = g(); x < y® ) ... §\C{// relational expression}§
    622622while ( ®struct S { int i; } x = { f() }; x.i < 4® ) ... §\C{// relational expression}§
     
    892892\begin{cfa}
    893893switch ( x ) {
    894         ®int y = 1;®                                                    §\C{// unreachable initialization}§
    895         ®x = 7;®                                                                §\C{// unreachable code without label/branch}§
     894        ®int y = 1;® §\C{// unreachable initialization}§
     895        ®x = 7;® §\C{// unreachable code without label/branch}§
    896896  case 0: ...
    897897        ...
    898         ®int z = 0;®                                                    §\C{// unreachable initialization, cannot appear after case}§
     898        ®int z = 0;® §\C{// unreachable initialization, cannot appear after case}§
    899899        z = 2;
    900900  case 1:
    901         ®x = z;®                                                                §\C{// without fall through, z is uninitialized}§
     901        ®x = z;® §\C{// without fall through, z is uninitialized}§
    902902}
    903903\end{cfa}
     
    937937  ®case 5:
    938938        ...
    939         ®fallthru®;                                                             §\C{// explicit fall through}§
     939        ®fallthru®; §\C{// explicit fall through}§
    940940  case 7:
    941941        ...
    942         ®break®                                                                 §\C{// explicit end of switch (redundant)}§
     942        ®break® §\C{// explicit end of switch (redundant)}§
    943943  default:
    944944        j = 3;
     
    961961\begin{cfa}
    962962switch ( x ) {
    963         ®int i = 0;®                                                    §\C{// allowed only at start}§
     963        ®int i = 0;® §\C{// allowed only at start}§
    964964  case 0:
    965965        ...
    966         ®int j = 0;®                                                    §\C{// disallowed}§
     966        ®int j = 0;® §\C{// disallowed}§
    967967  case 1:
    968968        {
    969                 ®int k = 0;®                                            §\C{// allowed at different nesting levels}§
     969                ®int k = 0;® §\C{// allowed at different nesting levels}§
    970970                ...
    971           ®case 2:®                                                             §\C{// disallow case in nested statements}§
     971          ®case 2:® §\C{// disallow case in nested statements}§
    972972        }
    973973  ...
     
    10191019\begin{cfa}
    10201020switch ( i ) {
    1021   case ®1~5:®                                   §\C{// 1, 2, 3, 4, 5}§
     1021  case ®1~5:® §\C{// 1, 2, 3, 4, 5}§
    10221022        ...
    1023   case ®10~15:®                                 §\C{// 10, 11, 12, 13, 14, 15}§
     1023  case ®10~15:® §\C{// 10, 11, 12, 13, 14, 15}§
    10241024        ...
    10251025}
     
    11521152Grouping heterogeneous data into \newterm{aggregate}s (structure/union) is a common programming practice, and an aggregate can be further organized into more complex structures, such as arrays and containers:
    11531153\begin{cfa}
    1154 struct S {                                                                      §\C{// aggregate}§
    1155         char c;                                                                 §\C{// fields}§
     1154struct S { §\C{// aggregate}§
     1155        char c; §\C{// fields}§
    11561156        int i;
    11571157        double d;
     
    11621162\begin{cfa}
    11631163void f( S s ) {
    1164         ®s.®c; ®s.®i; ®s.®d;                                    §\C{// access containing fields}§
     1164        ®s.®c; ®s.®i; ®s.®d; §\C{// access containing fields}§
    11651165}
    11661166\end{cfa}
     
    11691169\begin{C++}
    11701170struct S {
    1171         char c;                                                                 §\C{// fields}§
     1171        char c; §\C{// fields}§
    11721172        int i;
    11731173        double d;
    1174         void f() {                                                              §\C{// implicit ``this'' aggregate}§
    1175                 ®this->®c; ®this->®i; ®this->®d;        §\C{// access containing fields}§
     1174        void f() { §\C{// implicit ``this'' aggregate}§
     1175                ®this->®c; ®this->®i; ®this->®d; §\C{// access containing fields}§
    11761176        }
    11771177}
     
    11811181\begin{cfa}
    11821182struct T { double m, n; };
    1183 int S::f( T & t ) {                                                     §\C{// multiple aggregate parameters}§
    1184         c; i; d;                                                                §\C{\color{red}// this--{\textgreater}.c, this--{\textgreater}.i, this--{\textgreater}.d}§
    1185         ®t.®m; ®t.®n;                                                   §\C{// must qualify}§
     1183int S::f( T & t ) { §\C{// multiple aggregate parameters}§
     1184        c; i; d; §\C{\color{red}// this--{\textgreater}.c, this--{\textgreater}.i, this--{\textgreater}.d}§
     1185        ®t.®m; ®t.®n; §\C{// must qualify}§
    11861186}
    11871187\end{cfa}
     
    11901190Hence, the qualified fields become variables with the side-effect that it is easier to optimizing field references in a block.
    11911191\begin{cfa}
    1192 void f( S & this ) ®with ( this )® {            §\C{// with statement}§
    1193         c; i; d;                                                                §\C{\color{red}// this.c, this.i, this.d}§
     1192void f( S & this ) ®with ( this )® { §\C{// with statement}§
     1193        c; i; d; §\C{\color{red}// this.c, this.i, this.d}§
    11941194}
    11951195\end{cfa}
    11961196with the generality of opening multiple aggregate-parameters:
    11971197\begin{cfa}
    1198 void f( S & s, T & t ) ®with ( s, t )® {        §\C{// multiple aggregate parameters}§
    1199         c; i; d;                                                                §\C{\color{red}// s.c, s.i, s.d}§
    1200         m; n;                                                                   §\C{\color{red}// t.m, t.n}§
     1198void f( S & s, T & t ) ®with ( s, t )® { §\C{// multiple aggregate parameters}§
     1199        c; i; d; §\C{\color{red}// s.c, s.i, s.d}§
     1200        m; n; §\C{\color{red}// t.m, t.n}§
    12011201}
    12021202\end{cfa}
     
    12201220struct T { int ®i®; int k; int m; } t, w;
    12211221with ( s, t ) {
    1222         j + k;                                                                  §\C{// unambiguous, s.j + t.k}§
    1223         m = 5.0;                                                                §\C{// unambiguous, t.m = 5.0}§
    1224         m = 1;                                                                  §\C{// unambiguous, s.m = 1}§
    1225         int a = m;                                                              §\C{// unambiguous, a = s.i }§
    1226         double b = m;                                                   §\C{// unambiguous, b = t.m}§
    1227         int c = s.i + t.i;                                              §\C{// unambiguous, qualification}§
    1228         (double)m;                                                              §\C{// unambiguous, cast}§
     1222        j + k; §\C{// unambiguous, s.j + t.k}§
     1223        m = 5.0; §\C{// unambiguous, t.m = 5.0}§
     1224        m = 1; §\C{// unambiguous, s.m = 1}§
     1225        int a = m; §\C{// unambiguous, a = s.i }§
     1226        double b = m; §\C{// unambiguous, b = t.m}§
     1227        int c = s.i + t.i; §\C{// unambiguous, qualification}§
     1228        (double)m; §\C{// unambiguous, cast}§
    12291229}
    12301230\end{cfa}
     
    12361236There is an interesting problem between parameters and the function-body ©with©, \eg:
    12371237\begin{cfa}
    1238 void ?{}( S & s, int i ) with ( s ) {           §\C{// constructor}§
    1239         ®s.i = i;®  j = 3;  m = 5.5;                    §\C{// initialize fields}§
     1238void ?{}( S & s, int i ) with ( s ) { §\C{// constructor}§
     1239        ®s.i = i;®  j = 3;  m = 5.5; §\C{// initialize fields}§
    12401240}
    12411241\end{cfa}
     
    12561256Finally, a cast may be used to disambiguate among overload variables in a ©with© expression:
    12571257\begin{cfa}
    1258 with ( w ) { ... }                                                      §\C{// ambiguous, same name and no context}§
    1259 with ( (S)w ) { ... }                                           §\C{// unambiguous, cast}§
     1258with ( w ) { ... } §\C{// ambiguous, same name and no context}§
     1259with ( (S)w ) { ... } §\C{// unambiguous, cast}§
    12601260\end{cfa}
    12611261and ©with© expressions may be complex expressions with type reference (see Section~\ref{s:References}) to aggregate:
    12621262% \begin{cfa}
    12631263% struct S { int i, j; } sv;
    1264 % with ( sv ) {                                                         §\C{// implicit reference}§
     1264% with ( sv ) { §\C{// implicit reference}§
    12651265%       S & sr = sv;
    1266 %       with ( sr ) {                                                   §\C{// explicit reference}§
     1266%       with ( sr ) { §\C{// explicit reference}§
    12671267%               S * sp = &sv;
    1268 %               with ( *sp ) {                                          §\C{// computed reference}§
    1269 %                       i = 3; j = 4;                                   §\C{\color{red}// sp--{\textgreater}i, sp--{\textgreater}j}§
     1268%               with ( *sp ) { §\C{// computed reference}§
     1269%                       i = 3; j = 4; §\C{\color{red}// sp--{\textgreater}i, sp--{\textgreater}j}§
    12701270%               }
    1271 %               i = 2; j = 3;                                           §\C{\color{red}// sr.i, sr.j}§
     1271%               i = 2; j = 3; §\C{\color{red}// sr.i, sr.j}§
    12721272%       }
    1273 %       i = 1; j = 2;                                                   §\C{\color{red}// sv.i, sv.j}§
     1273%       i = 1; j = 2; §\C{\color{red}// sv.i, sv.j}§
    12741274% }
    12751275% \end{cfa}
     
    12791279class C {
    12801280        int i, j;
    1281         int mem() {                                                             §\C{\color{red}// implicit "this" parameter}§
    1282                 i = 1;                                                          §\C{\color{red}// this->i}§
    1283                 j = 2;                                                          §\C{\color{red}// this->j}§
     1281        int mem() { §\C{\color{red}// implicit "this" parameter}§
     1282                i = 1; §\C{\color{red}// this->i}§
     1283                j = 2; §\C{\color{red}// this->j}§
    12841284        }
    12851285}
     
    12881288\begin{cfa}
    12891289struct S { int i, j; };
    1290 int mem( S & ®this® ) {                                         §\C{// explicit "this" parameter}§
    1291         ®this.®i = 1;                                                   §\C{// "this" is not elided}§
     1290int mem( S & ®this® ) { §\C{// explicit "this" parameter}§
     1291        ®this.®i = 1; §\C{// "this" is not elided}§
    12921292        ®this.®j = 2;
    12931293}
     
    12971297\CFA provides a ©with© clause/statement (see Pascal~\cite[\S~4.F]{Pascal}) to elided the "©this.©" by opening a scope containing field identifiers, changing the qualified fields into variables and giving an opportunity for optimizing qualified references.
    12981298\begin{cfa}
    1299 int mem( S & this ) ®with( this )® {            §\C{// with clause}§
    1300         i = 1;                                                                  §\C{\color{red}// this.i}§
    1301         j = 2;                                                                  §\C{\color{red}// this.j}§
     1299int mem( S & this ) ®with( this )® { §\C{// with clause}§
     1300        i = 1; §\C{\color{red}// this.i}§
     1301        j = 2; §\C{\color{red}// this.j}§
    13021302}
    13031303\end{cfa}
     
    13161316        struct S1 { ... } s1;
    13171317        struct S2 { ... } s2;
    1318         ®with( s1 )® {                                                  §\C{// with statement}§
     1318        ®with( s1 )® { §\C{// with statement}§
    13191319                // access fields of s1 without qualification
    1320                 ®with s2® {                                                     §\C{// nesting}§
     1320                ®with s2® { §\C{// nesting}§
    13211321                        // access fields of s1 and s2 without qualification
    13221322                }
     
    13731373Non-local transfer can cause stack unwinding, \ie non-local routine termination, depending on the kind of raise.
    13741374\begin{cfa}
    1375 exception_t E {};                                                       §\C{// exception type}§
     1375exception_t E {}; §\C{// exception type}§
    13761376void f(...) {
    1377         ... throw E{}; ...                                              §\C{// termination}§
    1378         ... throwResume E{}; ...                                §\C{// resumption}§
     1377        ... throw E{}; ... §\C{// termination}§
     1378        ... throwResume E{}; ... §\C{// resumption}§
    13791379}
    13801380try {
     
    14421442For example, a routine returning a \Index{pointer} to an array of integers is defined and used in the following way:
    14431443\begin{cfa}
    1444 int ®(*®f®())[®5®]® {...};                              §\C{// definition}§
    1445  ... ®(*®f®())[®3®]® += 1;                              §\C{// usage}§
     1444int ®(*®f®())[®5®]® {...}; §\C{// definition}§
     1445 ... ®(*®f®())[®3®]® += 1; §\C{// usage}§
    14461446\end{cfa}
    14471447Essentially, the return type is wrapped around the routine name in successive layers (like an \Index{onion}).
     
    16351635*x = 3;                 // implicit dereference
    16361636int * ®const® y = (int *)104;
    1637 *y = *x;                // implicit dereference
     1637*y = *x;                        // implicit dereference
    16381638\end{cfa}
    16391639\end{tabular}
     
    16491649\hline
    16501650\begin{cfa}
    1651 lda             r1,100  // load address of x
    1652 ld               r2,(r1)          // load value of x
    1653 lda             r3,104  // load address of y
    1654 st               r2,(r3)          // store x into y
     1651lda             r1,100   // load address of x
     1652ld               r2,(r1)   // load value of x
     1653lda             r3,104   // load address of y
     1654st               r2,(r3)   // store x into y
    16551655\end{cfa}
    16561656&
    16571657\begin{cfa}
    16581658
    1659 ld              r2,(100)        // load value of x
    1660 
    1661 st              r2,(104)        // store x into y
     1659ld              r2,(100)   // load value of x
     1660
     1661st              r2,(104)   // store x into y
    16621662\end{cfa}
    16631663\end{tabular}
     
    16731673\begin{cfa}
    16741674int x, y, ®*® p1, ®*® p2, ®**® p3;
    1675 p1 = ®&®x;              // p1 points to x
    1676 p2 = p1;                // p2 points to x
    1677 p1 = ®&®y;              // p1 points to y
    1678 p3 = &p2;               // p3 points to p2
     1675p1 = ®&®x;    // p1 points to x
     1676p2 = p1;    // p2 points to x
     1677p1 = ®&®y;    // p1 points to y
     1678p3 = &p2;  // p3 points to p2
    16791679\end{cfa}
    16801680&
     
    16871687For example, \Index*{Algol68}~\cite{Algol68} infers pointer dereferencing to select the best meaning for each pointer usage
    16881688\begin{cfa}
    1689 p2 = p1 + x;                                    §\C{// compiler infers *p2 = *p1 + x;}§
     1689p2 = p1 + x; §\C{// compiler infers *p2 = *p1 + x;}§
    16901690\end{cfa}
    16911691Algol68 infers the following dereferencing ©*p2 = *p1 + x©, because adding the arbitrary integer value in ©x© to the address of ©p1© and storing the resulting address into ©p2© is an unlikely operation.
     
    16951695In C, objects of pointer type always manipulate the pointer object's address:
    16961696\begin{cfa}
    1697 p1 = p2;                                                §\C{// p1 = p2\ \ rather than\ \ *p1 = *p2}§
    1698 p2 = p1 + x;                                    §\C{// p2 = p1 + x\ \ rather than\ \ *p2 = *p1 + x}§
     1697p1 = p2; §\C{// p1 = p2\ \ rather than\ \ *p1 = *p2}§
     1698p2 = p1 + x; §\C{// p2 = p1 + x\ \ rather than\ \ *p2 = *p1 + x}§
    16991699\end{cfa}
    17001700even though the assignment to ©p2© is likely incorrect, and the programmer probably meant:
    17011701\begin{cfa}
    1702 p1 = p2;                                                §\C{// pointer address assignment}§
    1703 ®*®p2 = ®*®p1 + x;                              §\C{// pointed-to value assignment / operation}§
     1702p1 = p2; §\C{// pointer address assignment}§
     1703®*®p2 = ®*®p1 + x; §\C{// pointed-to value assignment / operation}§
    17041704\end{cfa}
    17051705The C semantics work well for situations where manipulation of addresses is the primary meaning and data is rarely accessed, such as storage management (©malloc©/©free©).
     
    17181718\begin{cfa}
    17191719int x, y, ®&® r1, ®&® r2, ®&&® r3;
    1720 ®&®r1 = &x;                                             §\C{// r1 points to x}§
    1721 ®&®r2 = &r1;                                    §\C{// r2 points to x}§
    1722 ®&®r1 = &y;                                             §\C{// r1 points to y}§
    1723 ®&&®r3 = ®&®&r2;                                §\C{// r3 points to r2}§
     1720®&®r1 = &x; §\C{// r1 points to x}§
     1721®&®r2 = &r1; §\C{// r2 points to x}§
     1722®&®r1 = &y; §\C{// r1 points to y}§
     1723®&&®r3 = ®&®&r2; §\C{// r3 points to r2}§
    17241724r2 = ((r1 + r2) * (r3 - r1)) / (r3 - 15); §\C{// implicit dereferencing}§
    17251725\end{cfa}
     
    17371737For a \CFA reference type, the cancellation on the left-hand side of assignment leaves the reference as an address (\Index{lvalue}):
    17381738\begin{cfa}
    1739 (&®*®)r1 = &x;                                  §\C{// (\&*) cancel giving address in r1 not variable pointed-to by r1}§
     1739(&®*®)r1 = &x; §\C{// (\&*) cancel giving address in r1 not variable pointed-to by r1}§
    17401740\end{cfa}
    17411741Similarly, the address of a reference can be obtained for assignment or computation (\Index{rvalue}):
    17421742\begin{cfa}
    1743 (&(&®*®)®*®)r3 = &(&®*®)r2;             §\C{// (\&*) cancel giving address in r2, (\&(\&*)*) cancel giving address in r3}§
     1743(&(&®*®)®*®)r3 = &(&®*®)r2; §\C{// (\&*) cancel giving address in r2, (\&(\&*)*) cancel giving address in r3}§
    17441744\end{cfa}
    17451745Cancellation\index{cancellation!pointer/reference}\index{pointer!cancellation} works to arbitrary depth.
     
    17491749int x, *p1 = &x, **p2 = &p1, ***p3 = &p2,
    17501750                 &r1 = x,    &&r2 = r1,   &&&r3 = r2;
    1751 ***p3 = 3;                                              §\C{// change x}§
    1752 r3 = 3;                                                 §\C{// change x, ***r3}§
    1753 **p3 = ...;                                             §\C{// change p1}§
    1754 &r3 = ...;                                              §\C{// change r1, (\&*)**r3, 1 cancellation}§
    1755 *p3 = ...;                                              §\C{// change p2}§
    1756 &&r3 = ...;                                             §\C{// change r2, (\&(\&*)*)*r3, 2 cancellations}§
    1757 &&&r3 = p3;                                             §\C{// change r3 to p3, (\&(\&(\&*)*)*)r3, 3 cancellations}§
     1751***p3 = 3; §\C{// change x}§
     1752r3 = 3; §\C{// change x, ***r3}§
     1753**p3 = ...; §\C{// change p1}§
     1754&r3 = ...; §\C{// change r1, (\&*)**r3, 1 cancellation}§
     1755*p3 = ...; §\C{// change p2}§
     1756&&r3 = ...; §\C{// change r2, (\&(\&*)*)*r3, 2 cancellations}§
     1757&&&r3 = p3; §\C{// change r3 to p3, (\&(\&(\&*)*)*)r3, 3 cancellations}§
    17581758\end{cfa}
    17591759Furthermore, both types are equally performant, as the same amount of dereferencing occurs for both types.
     
    17621762As for a pointer type, a reference type may have qualifiers:
    17631763\begin{cfa}
    1764 const int cx = 5;                                       §\C{// cannot change cx;}§
    1765 const int & cr = cx;                            §\C{// cannot change what cr points to}§
    1766 ®&®cr = &cx;                                            §\C{// can change cr}§
    1767 cr = 7;                                                         §\C{// error, cannot change cx}§
    1768 int & const rc = x;                                     §\C{// must be initialized}§
    1769 ®&®rc = &x;                                                     §\C{// error, cannot change rc}§
    1770 const int & const crc = cx;                     §\C{// must be initialized}§
    1771 crc = 7;                                                        §\C{// error, cannot change cx}§
    1772 ®&®crc = &cx;                                           §\C{// error, cannot change crc}§
     1764const int cx = 5; §\C{// cannot change cx;}§
     1765const int & cr = cx; §\C{// cannot change what cr points to}§
     1766®&®cr = &cx; §\C{// can change cr}§
     1767cr = 7; §\C{// error, cannot change cx}§
     1768int & const rc = x; §\C{// must be initialized}§
     1769®&®rc = &x; §\C{// error, cannot change rc}§
     1770const int & const crc = cx; §\C{// must be initialized}§
     1771crc = 7; §\C{// error, cannot change cx}§
     1772®&®crc = &cx; §\C{// error, cannot change crc}§
    17731773\end{cfa}
    17741774Hence, for type ©& const©, there is no pointer assignment, so ©&rc = &x© is disallowed, and \emph{the address value cannot be the null pointer unless an arbitrary pointer is coerced\index{coercion} into the reference}:
    17751775\begin{cfa}
    1776 int & const cr = *0;                            §\C{// where 0 is the int * zero}§
     1776int & const cr = *0; §\C{// where 0 is the int * zero}§
    17771777\end{cfa}
    17781778Note, constant reference-types do not prevent \Index{addressing errors} because of explicit storage-management:
     
    17811781cr = 5;
    17821782free( &cr );
    1783 cr = 7;                                                         §\C{// unsound pointer dereference}§
     1783cr = 7; §\C{// unsound pointer dereference}§
    17841784\end{cfa}
    17851785
     
    18061806\begin{cfa}
    18071807int w, x, y, z, & ar[3] = { x, y, z }; §\C{// initialize array of references}§
    1808 &ar[1] = &w;                                            §\C{// change reference array element}§
    1809 typeof( ar[1] ) p;                                      §\C{// (gcc) is int, \ie the type of referenced object}§
    1810 typeof( &ar[1] ) q;                                     §\C{// (gcc) is int \&, \ie the type of reference}§
    1811 sizeof( ar[1] ) == sizeof( int );       §\C{// is true, \ie the size of referenced object}§
    1812 sizeof( &ar[1] ) == sizeof( int *)      §\C{// is true, \ie the size of a reference}§
     1808&ar[1] = &w; §\C{// change reference array element}§
     1809typeof( ar[1] ) p; §\C{// (gcc) is int, \ie the type of referenced object}§
     1810typeof( &ar[1] ) q; §\C{// (gcc) is int \&, \ie the type of reference}§
     1811sizeof( ar[1] ) == sizeof( int ); §\C{// is true, \ie the size of referenced object}§
     1812sizeof( &ar[1] ) == sizeof( int *) §\C{// is true, \ie the size of a reference}§
    18131813\end{cfa}
    18141814
     
    18271827Therefore, for pointer/reference initialization, the initializing value must be an address not a value.
    18281828\begin{cfa}
    1829 int * p = &x;                                           §\C{// assign address of x}§
    1830 ®int * p = x;®                                          §\C{// assign value of x}§
    1831 int & r = x;                                            §\C{// must have address of x}§
     1829int * p = &x; §\C{// assign address of x}§
     1830®int * p = x;® §\C{// assign value of x}§
     1831int & r = x; §\C{// must have address of x}§
    18321832\end{cfa}
    18331833Like the previous example with C pointer-arithmetic, it is unlikely assigning the value of ©x© into a pointer is meaningful (again, a warning is usually given).
     
    18381838Similarly, when a reference type is used for a parameter/return type, the call-site argument does not require a reference operator for the same reason.
    18391839\begin{cfa}
    1840 int & f( int & r );                                     §\C{// reference parameter and return}§
    1841 z = f( x ) + f( y );                            §\C{// reference operator added, temporaries needed for call results}§
     1840int & f( int & r ); §\C{// reference parameter and return}§
     1841z = f( x ) + f( y ); §\C{// reference operator added, temporaries needed for call results}§
    18421842\end{cfa}
    18431843Within routine ©f©, it is possible to change the argument by changing the corresponding parameter, and parameter ©r© can be locally reassigned within ©f©.
     
    18661866void f( int & r );
    18671867void g( int * p );
    1868 f( 3 );                   g( ®&®3 );            §\C{// compiler implicit generates temporaries}§
    1869 f( x + y );             g( ®&®(x + y) );        §\C{// compiler implicit generates temporaries}§
     1868f( 3 );                   g( ®&®3 ); §\C{// compiler implicit generates temporaries}§
     1869f( x + y );             g( ®&®(x + y) ); §\C{// compiler implicit generates temporaries}§
    18701870\end{cfa}
    18711871Essentially, there is an implicit \Index{rvalue} to \Index{lvalue} conversion in this case.\footnote{
     
    18781878\begin{cfa}
    18791879void f( int i );
    1880 void (* fp)( int );                                     §\C{// routine pointer}§
    1881 fp = f;                                                         §\C{// reference initialization}§
    1882 fp = &f;                                                        §\C{// pointer initialization}§
    1883 fp = *f;                                                        §\C{// reference initialization}§
    1884 fp(3);                                                          §\C{// reference invocation}§
    1885 (*fp)(3);                                                       §\C{// pointer invocation}§
     1880void (* fp)( int ); §\C{// routine pointer}§
     1881fp = f; §\C{// reference initialization}§
     1882fp = &f; §\C{// pointer initialization}§
     1883fp = *f; §\C{// reference initialization}§
     1884fp(3); §\C{// reference invocation}§
     1885(*fp)(3); §\C{// pointer invocation}§
    18861886\end{cfa}
    18871887While C's treatment of routine objects has similarity to inferring a reference type in initialization contexts, the examples are assignment not initialization, and all possible forms of assignment are possible (©f©, ©&f©, ©*f©) without regard for type.
    18881888Instead, a routine object should be referenced by a ©const© reference:
    18891889\begin{cfa}
    1890 ®const® void (®&® fr)( int ) = f;       §\C{// routine reference}§
    1891 fr = ...                                                        §\C{// error, cannot change code}§
    1892 &fr = ...;                                                      §\C{// changing routine reference}§
    1893 fr( 3 );                                                        §\C{// reference call to f}§
    1894 (*fr)(3);                                                       §\C{// error, incorrect type}§
     1890®const® void (®&® fr)( int ) = f; §\C{// routine reference}§
     1891fr = ... §\C{// error, cannot change code}§
     1892&fr = ...; §\C{// changing routine reference}§
     1893fr( 3 ); §\C{// reference call to f}§
     1894(*fr)(3); §\C{// error, incorrect type}§
    18951895\end{cfa}
    18961896because the value of the routine object is a routine literal, \ie the routine code is normally immutable during execution.\footnote{
     
    19141914int x, * px, ** ppx, *** pppx, **** ppppx;
    19151915int & rx = x, && rrx = rx, &&& rrrx = rrx ;
    1916 x = rrrx;               // rrrx is an lvalue with type int &&& (equivalent to x)
    1917 px = &rrrx;             // starting from rrrx, &rrrx is an rvalue with type int *&&& (&x)
    1918 ppx = &&rrrx;   // starting from &rrrx, &&rrrx is an rvalue with type int **&& (&rx)
    1919 pppx = &&&rrrx; // starting from &&rrrx, &&&rrrx is an rvalue with type int ***& (&rrx)
    1920 ppppx = &&&&rrrx; // starting from &&&rrrx, &&&&rrrx is an rvalue with type int **** (&rrrx)
     1916x = rrrx; §\C[2.0in]{// rrrx is an lvalue with type int \&\&\& (equivalent to x)}§
     1917px = &rrrx; §\C{// starting from rrrx, \&rrrx is an rvalue with type int *\&\&\& (\&x)}§
     1918ppx = &&rrrx; §\C{// starting from \&rrrx, \&\&rrrx is an rvalue with type int **\&\& (\&rx)}§
     1919pppx = &&&rrrx; §\C{// starting from \&\&rrrx, \&\&\&rrrx is an rvalue with type int ***\& (\&rrx)}§
     1920ppppx = &&&&rrrx; §\C{// starting from \&\&\&rrrx, \&\&\&\&rrrx is an rvalue with type int **** (\&rrrx)}§
    19211921\end{cfa}
    19221922The following example shows the second rule applied to different \Index{lvalue} contexts:
     
    19241924int x, * px, ** ppx, *** pppx;
    19251925int & rx = x, && rrx = rx, &&& rrrx = rrx ;
    1926 rrrx = 2;               // rrrx is an lvalue with type int &&& (equivalent to x)
    1927 &rrrx = px;             // starting from rrrx, &rrrx is an rvalue with type int *&&& (rx)
    1928 &&rrrx = ppx;   // starting from &rrrx, &&rrrx is an rvalue with type int **&& (rrx)
    1929 &&&rrrx = pppx; // starting from &&rrrx, &&&rrrx is an rvalue with type int ***& (rrrx)
     1926rrrx = 2; §\C{// rrrx is an lvalue with type int \&\&\& (equivalent to x)}§
     1927&rrrx = px; §\C{// starting from rrrx, \&rrrx is an rvalue with type int *\&\&\& (rx)}§
     1928&&rrrx = ppx; §\C{// starting from \&rrrx, \&\&rrrx is an rvalue with type int **\&\& (rrx)}§
     1929&&&rrrx = pppx; §\C{// starting from \&\&rrrx, \&\&\&rrrx is an rvalue with type int ***\& (rrrx)}\CRT§
    19301930\end{cfa}
    19311931
     
    19401940\begin{cfa}
    19411941int x;
    1942 x + 1;                  // lvalue variable (int) converts to rvalue for expression
     1942x + 1; §\C[2.0in]{// lvalue variable (int) converts to rvalue for expression}§
    19431943\end{cfa}
    19441944An rvalue has no type qualifiers (©cv©), so the lvalue qualifiers are dropped.
     
    19501950\begin{cfa}
    19511951int x, &r = x, f( int p );
    1952 x = ®r® + f( ®r® );  // lvalue reference converts to rvalue
     1952x = ®r® + f( ®r® ); §\C{// lvalue reference converts to rvalue}§
    19531953\end{cfa}
    19541954An rvalue has no type qualifiers (©cv©), so the reference qualifiers are dropped.
     
    19571957lvalue to reference conversion: \lstinline[deletekeywords=lvalue]@lvalue-type cv1 T@ converts to ©cv2 T &©, which allows implicitly converting variables to references.
    19581958\begin{cfa}
    1959 int x, &r = ®x®, f( int & p ); // lvalue variable (int) convert to reference (int &)
    1960 f( ®x® );               // lvalue variable (int) convert to reference (int &)
     1959int x, &r = ®x®, f( int & p ); §\C{// lvalue variable (int) convert to reference (int \&)}§
     1960f( ®x® ); §\C{// lvalue variable (int) convert to reference (int \&)}§
    19611961\end{cfa}
    19621962Conversion can restrict a type, where ©cv1© $\le$ ©cv2©, \eg passing an ©int© to a ©const volatile int &©, which has low cost.
     
    19681968\begin{cfa}
    19691969int x, & f( int & p );
    1970 f( ®x + 3® );   // rvalue parameter (int) implicitly converts to lvalue temporary reference (int &)
    1971 ®&f®(...) = &x; // rvalue result (int &) implicitly converts to lvalue temporary reference (int &)
     1970f( ®x + 3® );   §\C[1.5in]{// rvalue parameter (int) implicitly converts to lvalue temporary reference (int \&)}§
     1971®&f®(...) = &x; §\C{// rvalue result (int \&) implicitly converts to lvalue temporary reference (int \&)}\CRT§
    19721972\end{cfa}
    19731973In both case, modifications to the temporary are inaccessible (\Index{warning}).
     
    21582158in both cases the type is assumed to be void as opposed to old style C defaults of int return type and unknown parameter types, respectively, as in:
    21592159\begin{cfa}
    2160 [§\,§] g();                                                     §\C{// no input or output parameters}§
    2161 [ void ] g( void );                                     §\C{// no input or output parameters}§
     2160[§\,§] g(); §\C{// no input or output parameters}§
     2161[ void ] g( void ); §\C{// no input or output parameters}§
    21622162\end{cfa}
    21632163
     
    21772177\begin{cfa}
    21782178typedef int foo;
    2179 int f( int (* foo) );                           §\C{// foo is redefined as a parameter name}§
     2179int f( int (* foo) ); §\C{// foo is redefined as a parameter name}§
    21802180\end{cfa}
    21812181The string ``©int (* foo)©'' declares a C-style named-parameter of type pointer to an integer (the parenthesis are superfluous), while the same string declares a \CFA style unnamed parameter of type routine returning integer with unnamed parameter of type pointer to foo.
     
    21852185C-style declarations can be used to declare parameters for \CFA style routine definitions, \eg:
    21862186\begin{cfa}
    2187 [ int ] f( * int, int * );                      §\C{// returns an integer, accepts 2 pointers to integers}§
    2188 [ * int, int * ] f( int );                      §\C{// returns 2 pointers to integers, accepts an integer}§
     2187[ int ] f( * int, int * ); §\C{// returns an integer, accepts 2 pointers to integers}§
     2188[ * int, int * ] f( int ); §\C{// returns 2 pointers to integers, accepts an integer}§
    21892189\end{cfa}
    21902190The reason for allowing both declaration styles in the new context is for backwards compatibility with existing preprocessor macros that generate C-style declaration-syntax, as in:
    21912191\begin{cfa}
    21922192#define ptoa( n, d ) int (*n)[ d ]
    2193 int f( ptoa( p, 5 ) ) ...                       §\C{// expands to int f( int (*p)[ 5 ] )}§
    2194 [ int ] f( ptoa( p, 5 ) ) ...           §\C{// expands to [ int ] f( int (*p)[ 5 ] )}§
     2193int f( ptoa( p, 5 ) ) ... §\C{// expands to int f( int (*p)[ 5 ] )}§
     2194[ int ] f( ptoa( p, 5 ) ) ... §\C{// expands to [ int ] f( int (*p)[ 5 ] )}§
    21952195\end{cfa}
    21962196Again, programmers are highly encouraged to use one declaration form or the other, rather than mixing the forms.
     
    22142214        int z;
    22152215        ... x = 0; ... y = z; ...
    2216         ®return;®                                                       §\C{// implicitly return x, y}§
     2216        ®return;® §\C{// implicitly return x, y}§
    22172217}
    22182218\end{cfa}
     
    22242224[ int x, int y ] f() {
    22252225        ...
    2226 }                                                                               §\C{// implicitly return x, y}§
     2226} §\C{// implicitly return x, y}§
    22272227\end{cfa}
    22282228In this case, the current values of ©x© and ©y© are returned to the calling routine just as if a ©return© had been encountered.
     
    22332233[ int x, int y ] f( int, x, int y ) {
    22342234        ...
    2235 }                                                                               §\C{// implicitly return x, y}§
     2235} §\C{// implicitly return x, y}§
    22362236\end{cfa}
    22372237This notation allows the compiler to eliminate temporary variables in nested routine calls.
    22382238\begin{cfa}
    2239 [ int x, int y ] f( int, x, int y );    §\C{// prototype declaration}§
     2239[ int x, int y ] f( int, x, int y ); §\C{// prototype declaration}§
    22402240int a, b;
    22412241[a, b] = f( f( f( a, b ) ) );
     
    22512251as well, parameter names are optional, \eg:
    22522252\begin{cfa}
    2253 [ int x ] f ();                                                 §\C{// returning int with no parameters}§
    2254 [ * int ] g (int y);                                    §\C{// returning pointer to int with int parameter}§
    2255 [ ] h ( int, char );                                    §\C{// returning no result with int and char parameters}§
    2256 [ * int, int ] j ( int );                               §\C{// returning pointer to int and int, with int parameter}§
     2253[ int x ] f (); §\C{// returning int with no parameters}§
     2254[ * int ] g (int y); §\C{// returning pointer to int with int parameter}§
     2255[ ] h ( int, char ); §\C{// returning no result with int and char parameters}§
     2256[ * int, int ] j ( int ); §\C{// returning pointer to int and int, with int parameter}§
    22572257\end{cfa}
    22582258This syntax allows a prototype declaration to be created by cutting and pasting source text from the routine definition header (or vice versa).
     
    22752275The syntax for pointers to \CFA routines specifies the pointer name on the right, \eg:
    22762276\begin{cfa}
    2277 * [ int x ] () fp;                                              §\C{// pointer to routine returning int with no parameters}§
    2278 * [ * int ] (int y) gp;                                 §\C{// pointer to routine returning pointer to int with int parameter}§
    2279 * [ ] (int,char) hp;                                    §\C{// pointer to routine returning no result with int and char parameters}§
    2280 * [ * int,int ] ( int ) jp;                             §\C{// pointer to routine returning pointer to int and int, with int parameter}§
     2277* [ int x ] () fp; §\C{// pointer to routine returning int with no parameters}§
     2278* [ * int ] (int y) gp; §\C{// pointer to routine returning pointer to int with int parameter}§
     2279* [ ] (int,char) hp; §\C{// pointer to routine returning no result with int and char parameters}§
     2280* [ * int,int ] ( int ) jp; §\C{// pointer to routine returning pointer to int and int, with int parameter}§
    22812281\end{cfa}
    22822282While parameter names are optional, \emph{a routine name cannot be specified};
    22832283for example, the following is incorrect:
    22842284\begin{cfa}
    2285 * [ int x ] f () fp;                                    §\C{// routine name "f" is not allowed}§
     2285* [ int x ] f () fp; §\C{// routine name "f" is not allowed}§
    22862286\end{cfa}
    22872287
     
    23062306whereas a named (keyword) call may be:
    23072307\begin{cfa}
    2308 p( z : 3, x : 4, y : 7 );       §\C{// rewrite $\Rightarrow$ p( 4, 7, 3 )}§
     2308p( z : 3, x : 4, y : 7 );  §\C{// rewrite $\Rightarrow$ p( 4, 7, 3 )}§
    23092309\end{cfa}
    23102310Here the order of the arguments is unimportant, and the names of the parameters are used to associate argument values with the corresponding parameters.
     
    23232323For example, the following routine prototypes and definition are all valid.
    23242324\begin{cfa}
    2325 void p( int, int, int );                        §\C{// equivalent prototypes}§
     2325void p( int, int, int ); §\C{// equivalent prototypes}§
    23262326void p( int x, int y, int z );
    23272327void p( int y, int x, int z );
    23282328void p( int z, int y, int x );
    2329 void p( int q, int r, int s ) {}        §\C{// match with this definition}§
     2329void p( int q, int r, int s ) {} §\C{// match with this definition}§
    23302330\end{cfa}
    23312331Forcing matching parameter names in routine prototypes with corresponding routine definitions is possible, but goes against a strong tradition in C programming.
     
    23392339int f( int x, double y );
    23402340
    2341 f( j : 3, i : 4 );                              §\C{// 1st f}§
    2342 f( x : 7, y : 8.1 );                    §\C{// 2nd f}§
    2343 f( 4, 5 );                                              §\C{// ambiguous call}§
     2341f( j : 3, i : 4 ); §\C{// 1st f}§
     2342f( x : 7, y : 8.1 ); §\C{// 2nd f}§
     2343f( 4, 5 );  §\C{// ambiguous call}§
    23442344\end{cfa}
    23452345However, named arguments compound routine resolution in conjunction with conversions:
    23462346\begin{cfa}
    2347 f( i : 3, 5.7 );                                §\C{// ambiguous call ?}§
     2347f( i : 3, 5.7 ); §\C{// ambiguous call ?}§
    23482348\end{cfa}
    23492349Depending on the cost associated with named arguments, this call could be resolvable or ambiguous.
     
    23592359the allowable positional calls are:
    23602360\begin{cfa}
    2361 p();                                                    §\C{// rewrite $\Rightarrow$ p( 1, 2, 3 )}§
    2362 p( 4 );                                                 §\C{// rewrite $\Rightarrow$ p( 4, 2, 3 )}§
    2363 p( 4, 4 );                                              §\C{// rewrite $\Rightarrow$ p( 4, 4, 3 )}§
    2364 p( 4, 4, 4 );                                   §\C{// rewrite $\Rightarrow$ p( 4, 4, 4 )}§
     2361p(); §\C{// rewrite $\Rightarrow$ p( 1, 2, 3 )}§
     2362p( 4 ); §\C{// rewrite $\Rightarrow$ p( 4, 2, 3 )}§
     2363p( 4, 4 ); §\C{// rewrite $\Rightarrow$ p( 4, 4, 3 )}§
     2364p( 4, 4, 4 ); §\C{// rewrite $\Rightarrow$ p( 4, 4, 4 )}§
    23652365// empty arguments
    2366 p(  , 4, 4 );                                   §\C{// rewrite $\Rightarrow$ p( 1, 4, 4 )}§
    2367 p( 4,  , 4 );                                   §\C{// rewrite $\Rightarrow$ p( 4, 2, 4 )}§
    2368 p( 4, 4,   );                                   §\C{// rewrite $\Rightarrow$ p( 4, 4, 3 )}§
    2369 p( 4,  ,   );                                   §\C{// rewrite $\Rightarrow$ p( 4, 2, 3 )}§
    2370 p(  , 4,   );                                   §\C{// rewrite $\Rightarrow$ p( 1, 4, 3 )}§
    2371 p(  ,  , 4 );                                   §\C{// rewrite $\Rightarrow$ p( 1, 2, 4 )}§
    2372 p(  ,  ,   );                                   §\C{// rewrite $\Rightarrow$ p( 1, 2, 3 )}§
     2366p(  , 4, 4 ); §\C{// rewrite $\Rightarrow$ p( 1, 4, 4 )}§
     2367p( 4,  , 4 ); §\C{// rewrite $\Rightarrow$ p( 4, 2, 4 )}§
     2368p( 4, 4,   ); §\C{// rewrite $\Rightarrow$ p( 4, 4, 3 )}§
     2369p( 4,  ,   ); §\C{// rewrite $\Rightarrow$ p( 4, 2, 3 )}§
     2370p(  , 4,   ); §\C{// rewrite $\Rightarrow$ p( 1, 4, 3 )}§
     2371p(  ,  , 4 ); §\C{// rewrite $\Rightarrow$ p( 1, 2, 4 )}§
     2372p(  ,  ,   ); §\C{// rewrite $\Rightarrow$ p( 1, 2, 3 )}§
    23732373\end{cfa}
    23742374Here the missing arguments are inserted from the default values in the parameter list.
     
    23942394Default values may only appear in a prototype versus definition context:
    23952395\begin{cfa}
    2396 void p( int x, int y = 2, int z = 3 );          §\C{// prototype: allowed}§
    2397 void p( int, int = 2, int = 3 );                        §\C{// prototype: allowed}§
    2398 void p( int x, int y = 2, int z = 3 ) {}        §\C{// definition: not allowed}§
     2396void p( int x, int y = 2, int z = 3 ); §\C{// prototype: allowed}§
     2397void p( int, int = 2, int = 3 ); §\C{// prototype: allowed}§
     2398void p( int x, int y = 2, int z = 3 ) {} §\C{// definition: not allowed}§
    23992399\end{cfa}
    24002400The reason for this restriction is to allow separate compilation.
     
    24212421\begin{cfa}
    24222422void p( int x, int y = 2, int z = 3... );
    2423 p( 1, 4, 5, 6, z : 3 );         §\C{// assume p( /* positional */, ... , /* named */ );}§
    2424 p( 1, z : 3, 4, 5, 6 );         §\C{// assume p( /* positional */, /* named */, ... );}§
     2423p( 1, 4, 5, 6, z : 3 ); §\C{// assume p( /* positional */, ... , /* named */ );}§
     2424p( 1, z : 3, 4, 5, 6 ); §\C{// assume p( /* positional */, /* named */, ... );}§
    24252425\end{cfa}
    24262426The first call is an error because arguments 4 and 5 are actually positional not ellipse arguments;
     
    24522452Furthermore, overloading cannot handle accessing default arguments in the middle of a positional list, via a missing argument, such as:
    24532453\begin{cfa}
    2454 p( 1, /* default */, 5 );               §\C{// rewrite $\Rightarrow$ p( 1, 2, 5 )}§
     2454p( 1, /* default */, 5 ); §\C{// rewrite $\Rightarrow$ p( 1, 2, 5 )}§
    24552455\end{cfa}
    24562456
     
    24652465\begin{cfa}
    24662466struct {
    2467         int f1;                                 §\C{// named field}§
    2468         int f2 : 4;                             §\C{// named field with bit field size}§
    2469         int : 3;                                §\C{// unnamed field for basic type with bit field size}§
    2470         int ;                                   §\C{// disallowed, unnamed field}§
    2471         int *;                                  §\C{// disallowed, unnamed field}§
    2472         int (*)( int );                 §\C{// disallowed, unnamed field}§
     2467        int f1; §\C{// named field}§
     2468        int f2 : 4; §\C{// named field with bit field size}§
     2469        int : 3; §\C{// unnamed field for basic type with bit field size}§
     2470        int ; §\C{// disallowed, unnamed field}§
     2471        int *; §\C{// disallowed, unnamed field}§
     2472        int (*)( int ); §\C{// disallowed, unnamed field}§
    24732473};
    24742474\end{cfa}
     
    24782478\begin{cfa}
    24792479struct {
    2480         int , , ;                               §\C{// 3 unnamed fields}§
     2480        int , , ; §\C{// 3 unnamed fields}§
    24812481}
    24822482\end{cfa}
     
    25722572const unsigned int size = 5;
    25732573int ia[size];
    2574 ...                                             §\C{// assign values to array ia}§
    2575 qsort( ia, size );              §\C{// sort ascending order using builtin ?<?}§
     2574... §\C{// assign values to array ia}§
     2575qsort( ia, size ); §\C{// sort ascending order using builtin ?<?}§
    25762576{
    25772577        ®int ?<?( int x, int y ) { return x > y; }® §\C{// nested routine}§
    2578         qsort( ia, size );      §\C{// sort descending order by local redefinition}§
     2578        qsort( ia, size ); §\C{// sort descending order by local redefinition}§
    25792579}
    25802580\end{cfa}
     
    25842584The following program in undefined in \CFA (and Indexc{gcc})
    25852585\begin{cfa}
    2586 [* [int]( int )] foo() {                §\C{// int (* foo())( int )}§
     2586[* [int]( int )] foo() { §\C{// int (* foo())( int )}§
    25872587        int ®i® = 7;
    25882588        int bar( int p ) {
    2589                 ®i® += 1;                               §\C{// dependent on local variable}§
     2589                ®i® += 1; §\C{// dependent on local variable}§
    25902590                sout | ®i®;
    25912591        }
    2592         return bar;                                     §\C{// undefined because of local dependence}§
     2592        return bar; §\C{// undefined because of local dependence}§
    25932593}
    25942594int main() {
    2595         * [int]( int ) fp = foo();      §\C{// int (* fp)( int )}§
     2595        * [int]( int ) fp = foo(); §\C{// int (* fp)( int )}§
    25962596        sout | fp( 3 );
    25972597}
     
    26062606In C and \CFA, lists of elements appear in several contexts, such as the parameter list of a routine call.
    26072607\begin{cfa}
    2608 f( ®2, x, 3 + i® );                             §\C{// element list}§
     2608f( ®2, x, 3 + i® ); §\C{// element list}§
    26092609\end{cfa}
    26102610A list of elements is called a \newterm{tuple}, and is different from a \Index{comma expression}.
     
    26232623typedef struct { int quot, rem; } div_t;        §\C[7cm]{// from include stdlib.h}§
    26242624div_t div( int num, int den );
    2625 div_t qr = div( 13, 5 );                                        §\C{// return quotient/remainder aggregate}§
    2626 printf( "%d %d\n", qr.quot, qr.rem );           §\C{// print quotient/remainder}§
     2625div_t qr = div( 13, 5 ); §\C{// return quotient/remainder aggregate}§
     2626printf( "%d %d\n", qr.quot, qr.rem ); §\C{// print quotient/remainder}§
    26272627\end{cfa}
    26282628This approach requires a name for the return type and fields, where \Index{naming} is a common programming-language issue.
     
    26342634For example, consider C's \Indexc{modf} function, which returns the integral and fractional part of a floating value.
    26352635\begin{cfa}
    2636 double modf( double x, double * i );            §\C{// from include math.h}§
    2637 double intp, frac = modf( 13.5, &intp );        §\C{// return integral and fractional components}§
    2638 printf( "%g %g\n", intp, frac );                        §\C{// print integral/fractional components}§
     2636double modf( double x, double * i ); §\C{// from include math.h}§
     2637double intp, frac = modf( 13.5, &intp ); §\C{// return integral and fractional components}§
     2638printf( "%g %g\n", intp, frac ); §\C{// print integral/fractional components}§
    26392639\end{cfa}
    26402640This approach requires allocating storage for the return values, which complicates the call site with a sequence of variable declarations leading to the call.
     
    26632663When a function call is passed as an argument to another call, the best match of actual arguments to formal parameters is evaluated given all possible expression interpretations in the current scope.
    26642664\begin{cfa}
    2665 void g( int, int );                                                     §\C{// 1}§
    2666 void g( double, double );                                       §\C{// 2}§
    2667 g( div( 13, 5 ) );                                                      §\C{// select 1}§
    2668 g( modf( 13.5 ) );                                                      §\C{// select 2}§
     2665void g( int, int ); §\C{// 1}§
     2666void g( double, double ); §\C{// 2}§
     2667g( div( 13, 5 ) ); §\C{// select 1}§
     2668g( modf( 13.5 ) ); §\C{// select 2}§
    26692669\end{cfa}
    26702670In this case, there are two overloaded ©g© routines.
     
    26752675The previous examples can be rewritten passing the multiple returned-values directly to the ©printf© function call.
    26762676\begin{cfa}
    2677 [ int, int ] div( int x, int y );                       §\C{// from include stdlib}§
    2678 printf( "%d %d\n", div( 13, 5 ) );                      §\C{// print quotient/remainder}§
    2679 
    2680 [ double, double ] modf( double x );            §\C{// from include math}§
    2681 printf( "%g %g\n", modf( 13.5 ) );                      §\C{// print integral/fractional components}§
     2677[ int, int ] div( int x, int y ); §\C{// from include stdlib}§
     2678printf( "%d %d\n", div( 13, 5 ) ); §\C{// print quotient/remainder}§
     2679
     2680[ double, double ] modf( double x ); §\C{// from include math}§
     2681printf( "%g %g\n", modf( 13.5 ) ); §\C{// print integral/fractional components}§
    26822682\end{cfa}
    26832683This approach provides the benefits of compile-time checking for appropriate return statements as in aggregation, but without the required verbosity of declaring a new named type.
     
    26892689\begin{cfa}
    26902690int quot, rem;
    2691 [ quot, rem ] = div( 13, 5 );                           §\C{// assign multiple variables}§
    2692 printf( "%d %d\n", quot, rem );                         §\C{// print quotient/remainder}\CRT§
     2691[ quot, rem ] = div( 13, 5 ); §\C{// assign multiple variables}§
     2692printf( "%d %d\n", quot, rem ); §\C{// print quotient/remainder}\CRT§
    26932693\end{cfa}
    26942694Here, the multiple return-values are matched in much the same way as passing multiple return-values to multiple parameters in a call.
     
    27162716In \CFA, it is possible to overcome this restriction by declaring a \newterm{tuple variable}.
    27172717\begin{cfa}
    2718 [int, int] ®qr® = div( 13, 5 );                 §\C{// initialize tuple variable}§
    2719 printf( "%d %d\n", ®qr® );                              §\C{// print quotient/remainder}§
     2718[int, int] ®qr® = div( 13, 5 ); §\C{// initialize tuple variable}§
     2719printf( "%d %d\n", ®qr® ); §\C{// print quotient/remainder}§
    27202720\end{cfa}
    27212721It is now possible to match the multiple return-values to a single variable, in much the same way as \Index{aggregation}.
     
    27232723One way to access the individual components of a tuple variable is with assignment.
    27242724\begin{cfa}
    2725 [ quot, rem ] = qr;                                             §\C{// assign multiple variables}§
     2725[ quot, rem ] = qr; §\C{// assign multiple variables}§
    27262726\end{cfa}
    27272727
     
    27462746[int, double] * p;
    27472747
    2748 int y = x.0;                                                    §\C{// access int component of x}§
    2749 y = f().1;                                                              §\C{// access int component of f}§
    2750 p->0 = 5;                                                               §\C{// access int component of tuple pointed-to by p}§
    2751 g( x.1, x.0 );                                                  §\C{// rearrange x to pass to g}§
    2752 double z = [ x, f() ].0.1;                              §\C{// access second component of first component of tuple expression}§
     2748int y = x.0; §\C{// access int component of x}§
     2749y = f().1; §\C{// access int component of f}§
     2750p->0 = 5; §\C{// access int component of tuple pointed-to by p}§
     2751g( x.1, x.0 ); §\C{// rearrange x to pass to g}§
     2752double z = [ x, f() ].0.1; §\C{// access second component of first component of tuple expression}§
    27532753\end{cfa}
    27542754Tuple-index expressions can occur on any tuple-typed expression, including tuple-returning functions, square-bracketed tuple expressions, and other tuple-index expressions, provided the retrieved component is also a tuple.
     
    28172817double y;
    28182818[int, double] z;
    2819 [y, x] = 3.14;                                                  §\C{// mass assignment}§
     2819[y, x] = 3.14; §\C{// mass assignment}§
    28202820[x, y] = z;                                                         §\C{// multiple assignment}§
    28212821z = 10;                                                         §\C{// mass assignment}§
    2822 z = [x, y];                                                             §\C{// multiple assignment}§
     2822z = [x, y]; §\C{// multiple assignment}§
    28232823\end{cfa}
    28242824Let $L_i$ for $i$ in $[0, n)$ represent each component of the flattened left side, $R_i$ represent each component of the flattened right side of a multiple assignment, and $R$ represent the right side of a mass assignment.
     
    28642864        double c, d;
    28652865        [ void ] f( [ int, int ] );
    2866         f( [ c, a ] = [ b, d ] = 1.5 );  // assignments in parameter list
     2866        f( [ c, a ] = [ b, d ] = 1.5 ); §\C{// assignments in parameter list}§
    28672867\end{cfa}
    28682868The tuple expression begins with a mass assignment of ©1.5© into ©[b, d]©, which assigns ©1.5© into ©b©, which is truncated to ©1©, and ©1.5© into ©d©, producing the tuple ©[1, 1.5]© as a result.
     
    28772877\begin{cfa}
    28782878struct S;
    2879 void ?{}(S *);         // (1)
    2880 void ?{}(S *, int);    // (2)
    2881 void ?{}(S * double);  // (3)
    2882 void ?{}(S *, S);      // (4)
    2883 
    2884 [S, S] x = [3, 6.28];  // uses (2), (3), specialized constructors
    2885 [S, S] y;              // uses (1), (1), default constructor
    2886 [S, S] z = x.0;        // uses (4), (4), copy constructor
     2879void ?{}(S *); §\C{// (1)}§
     2880void ?{}(S *, int); §\C{// (2)}§
     2881void ?{}(S * double); §\C{// (3)}§
     2882void ?{}(S *, S); §\C{// (4)}§
     2883
     2884[S, S] x = [3, 6.28]; §\C{// uses (2), (3), specialized constructors}§
     2885[S, S] y; §\C{// uses (1), (1), default constructor}§
     2886[S, S] z = x.0; §\C{// uses (4), (4), copy constructor}§
    28872887\end{cfa}
    28882888In this example, ©x© is initialized by the multiple constructor calls ©?{}(&x.0, 3)© and ©?{}(&x.1, 6.28)©, while ©y© is initialized by two default constructor calls ©?{}(&y.0)© and ©?{}(&y.1)©.
     
    29252925A member-access tuple may be used anywhere a tuple can be used, \eg:
    29262926\begin{cfa}
    2927 s.[ y, z, x ] = [ 3, 3.2, 'x' ];                §\C{// equivalent to s.x = 'x', s.y = 3, s.z = 3.2}§
    2928 f( s.[ y, z ] );                                                §\C{// equivalent to f( s.y, s.z )}§
     2927s.[ y, z, x ] = [ 3, 3.2, 'x' ]; §\C{// equivalent to s.x = 'x', s.y = 3, s.z = 3.2}§
     2928f( s.[ y, z ] ); §\C{// equivalent to f( s.y, s.z )}§
    29292929\end{cfa}
    29302930Note, the fields appearing in a record-field tuple may be specified in any order;
     
    29362936void f( double, long );
    29372937
    2938 f( x.[ 0, 3 ] );                                                §\C{// f( x.0, x.3 )}§
    2939 x.[ 0, 1 ] = x.[ 1, 0 ];                                §\C{// [ x.0, x.1 ] = [ x.1, x.0 ]}§
     2938f( x.[ 0, 3 ] ); §\C{// f( x.0, x.3 )}§
     2939x.[ 0, 1 ] = x.[ 1, 0 ]; §\C{// [ x.0, x.1 ] = [ x.1, x.0 ]}§
    29402940[ long, int, long ] y = x.[ 2, 0, 2 ];
    29412941\end{cfa}
     
    29542954\begin{cfa}
    29552955[ int, float, double ] f();
    2956 [ double, float ] x = f().[ 2, 1 ];             §\C{// f() called once}§
     2956[ double, float ] x = f().[ 2, 1 ]; §\C{// f() called once}§
    29572957\end{cfa}
    29582958
     
    29672967That is, a cast can be used to select the type of an expression when it is ambiguous, as in the call to an overloaded function.
    29682968\begin{cfa}
    2969 int f();     // (1)
    2970 double f();  // (2)
    2971 
    2972 f();       // ambiguous - (1),(2) both equally viable
    2973 (int)f();  // choose (2)
     2969int f(); §\C{// (1)}§
     2970double f(); §\C{// (2)}§
     2971
     2972f(); §\C{// ambiguous - (1),(2) both equally viable}§
     2973(int)f(); §\C{// choose (2)}§
    29742974\end{cfa}
    29752975Since casting is a fundamental operation in \CFA, casts need to be given a meaningful interpretation in the context of tuples.
     
    29792979void g();
    29802980
    2981 (void)f();  // valid, ignore results
    2982 (int)g();   // invalid, void cannot be converted to int
     2981(void)f(); §\C{// valid, ignore results}§
     2982(int)g(); §\C{// invalid, void cannot be converted to int}§
    29832983
    29842984struct A { int x; };
    2985 (struct A)f();  // invalid, int cannot be converted to A
     2985(struct A)f(); §\C{// invalid, int cannot be converted to A}§
    29862986\end{cfa}
    29872987In C, line 4 is a valid cast, which calls ©f© and discards its result.
     
    29992999        [int, [int, int], int] g();
    30003000
    3001         ([int, double])f();           // (1) valid
    3002         ([int, int, int])g();         // (2) valid
    3003         ([void, [int, int]])g();      // (3) valid
    3004         ([int, int, int, int])g();    // (4) invalid
    3005         ([int, [int, int, int]])g();  // (5) invalid
     3001        ([int, double])f(); §\C{// (1) valid}§
     3002        ([int, int, int])g(); §\C{// (2) valid}§
     3003        ([void, [int, int]])g(); §\C{// (3) valid}§
     3004        ([int, int, int, int])g(); §\C{// (4) invalid}§
     3005        ([int, [int, int, int]])g(); §\C{// (5) invalid}§
    30063006\end{cfa}
    30073007
     
    30633063void f([int, int], int, int);
    30643064
    3065 f([0, 0], 0, 0);    // no cost
    3066 f(0, 0, 0, 0);      // cost for structuring
    3067 f([0, 0,], [0, 0]); // cost for flattening
    3068 f([0, 0, 0], 0);    // cost for flattening and structuring
     3065f([0, 0], 0, 0); §\C{// no cost}§
     3066f(0, 0, 0, 0); §\C{// cost for structuring}§
     3067f([0, 0,], [0, 0]); §\C{// cost for flattening}§
     3068f([0, 0, 0], 0); §\C{// cost for flattening and structuring}§
    30693069\end{cfa}
    30703070
     
    31293129[ unsigned int, char ]
    31303130[ double, double, double ]
    3131 [ * int, int * ]                §\C{// mix of CFA and ANSI}§
     3131[ * int, int * ] §\C{// mix of CFA and ANSI}§
    31323132[ * [ 5 ] int, * * char, * [ [ int, int ] ] (int, int) ]
    31333133\end{cfa}
     
    31363136Examples of declarations using tuple types are:
    31373137\begin{cfa}
    3138 [ int, int ] x;                 §\C{// 2 element tuple, each element of type int}§
    3139 * [ char, char ] y;             §\C{// pointer to a 2 element tuple}§
     3138[ int, int ] x; §\C{// 2 element tuple, each element of type int}§
     3139* [ char, char ] y; §\C{// pointer to a 2 element tuple}§
    31403140[ [ int, int ] ] z ([ int, int ]);
    31413141\end{cfa}
     
    31543154[ int, int ] w1;
    31553155[ int, int, int ] w2;
    3156 [ void ] f (int, int, int); /* three input parameters of type int */
    3157 [ void ] g ([ int, int, int ]); /* 3 element tuple as input */
     3156[ void ] f (int, int, int); §\C{// three input parameters of type int}§
     3157[ void ] g ([ int, int, int ]); §\C{3 element tuple as input}§
    31583158f( [ 1, 2, 3 ] );
    31593159f( w1, 3 );
     
    32353235[ int, int, int, int ] w = [ 1, 2, 3, 4 ];
    32363236int x = 5;
    3237 [ x, w ] = [ w, x ];            §\C{// all four tuple coercions}§
     3237[ x, w ] = [ w, x ]; §\C{// all four tuple coercions}§
    32383238\end{cfa}
    32393239Starting on the right-hand tuple in the last assignment statement, w is opened, producing a tuple of four values;
     
    33233323both these examples produce indeterminate results:
    33243324\begin{cfa}
    3325 f( x++, x++ );                          §\C{// C routine call with side effects in arguments}§
    3326 [ v1, v2 ] = [ x++, x++ ];      §\C{// side effects in righthand side of multiple assignment}§
     3325f( x++, x++ ); §\C{// C routine call with side effects in arguments}§
     3326[ v1, v2 ] = [ x++, x++ ]; §\C{// side effects in righthand side of multiple assignment}§
    33273327\end{cfa}
    33283328
     
    33463346
    33473347
    3348 \section{I/O Library}
    3349 \label{s:IOLibrary}
    3350 \index{input/output library}
    3351 
    3352 The goal of \CFA I/O is to simplify the common cases\index{I/O!common case}, while fully supporting polymorphism and user defined types in a consistent way.
    3353 The approach combines ideas from \CC and Python.
    3354 The \CFA header file for the I/O library is \Indexc{fstream}.
    3355 
    3356 The common case is printing out a sequence of variables separated by whitespace.
     3348\section{I/O Stream Library}
     3349\label{s:IOStreamLibrary}
     3350\index{input/output stream library}
     3351\index{stream library}
     3352
     3353The goal of \CFA input/output (I/O) is to simplify the common cases\index{I/O!common case}, while fully supporting polymorphism and user defined types in a consistent way.
     3354\CFA I/O combines ideas from C ©printf©, \CC, and Python.
     3355I/O can be unformatted or formatted.
     3356Unformatted means \CFA selects the output or input format for values that match with the type of a variable.
     3357Formatted means additional information is specified to augment how an output or input of value is interpreted.
     3358\CFA formatting is a cross between C ©printf© and \CC ©cout© manipulators.
     3359\begin{itemize}
     3360\item
     3361©printf© format codes are dense, making them difficult to read and remember.
     3362\CFA/\CC format manipulators are named, making them easier to read and remember.
     3363\item
     3364©printf© separates format codes from associated variables, making it difficult to match codes with variables.
     3365\CFA/\CC co-locate codes with associated variables, where \CFA has the tighter binding.
     3366\item
     3367Format manipulators in \CC have global rather than local effect, except ©setw©.
     3368Hence, it is common programming practice to toggle manipulators on and then back to the default to prevent downstream side-effects.
     3369Without this programming style, errors occur when moving prints, as manipulator effects incorrectly flow into the new location.
     3370(To guarantee no side-effects, manipulator values must be saved and restored across function calls.)
     3371\end{itemize}
     3372The \CFA header file for the I/O library is \Indexc{fstream.hfa}.
     3373
     3374For unformatted output, the common case is printing a sequence of variables separated by whitespace.
    33573375\begin{cquote}
    33583376\begin{tabular}{@{}l@{\hspace{3em}}l@{}}
     
    33733391&
    33743392\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    3375 1 2 3
     33931® ®2® ®3
    33763394\end{cfa}
    33773395\end{tabular}
    33783396\end{cquote}
    3379 The \CFA form has half the characters of the \CC form, and is similar to \Index*{Python} I/O with respect to implicit separators.
    3380 Similar simplification occurs for \Index{tuple} I/O, which prints all tuple values separated by ``\lstinline[showspaces=true]@, @''.
     3397The \CFA form has half the characters of the \CC form, and is similar to \Index*{Python} I/O with respect to implicit separators and newline.
     3398Similar simplification occurs for \Index{tuple} I/O, which flattens the tuple and prints each value separated by ``\lstinline[showspaces=true]@, @''.
    33813399\begin{cfa}
    33823400[int, [ int, int ] ] t1 = [ 1, [ 2, 3 ] ], t2 = [ 4, [ 5, 6 ] ];
    3383 sout | t1 | t2;                                         §\C{// print tuples}§
     3401sout | t1 | t2; §\C{// print tuples}§
    33843402\end{cfa}
    33853403\begin{cfa}[showspaces=true,aboveskip=0pt]
    338634041®, ®2®, ®3 4®, ®5®, ®6
    33873405\end{cfa}
    3388 Finally, \CFA uses the logical-or operator for I/O as it is the lowest-priority overloadable operator, other than assignment.
     3406Finally, \CFA uses the logical-or operator for I/O as it is the lowest-priority \emph{overloadable} operator, other than assignment.
    33893407Therefore, fewer output expressions require parenthesis.
    33903408\begin{cquote}
     
    33933411&
    33943412\begin{cfa}
    3395 sout | x * 3 | y + 1 | z << 2 | x == y | (x | y) | (x || y) | (x > z ? 1 : 2);
     3413sout | x * 3 | y + 1 | z << 2 | x == y | ®(®x | y®)® | ®(®x || y®)® | ®(®x > z ? 1 : 2®)®;
    33963414\end{cfa}
    33973415\\
     
    33993417&
    34003418\begin{cfa}
    3401 cout << x * 3 << y + 1 << ®(®z << 2®)® << ®(®x == y®)® << (x | y) << (x || y) << (x > z ? 1 : 2) << endl;
     3419cout << x * 3 << y + 1 << ®(®z << 2®)® << ®(®x == y®)® << ®(®x | y®)® << ®(®x || y®)® << ®(®x > z ? 1 : 2®)® << endl;
    34023420\end{cfa}
    34033421\\
     
    34083426\end{tabular}
    34093427\end{cquote}
    3410 There is a weak similarity between the \CFA logical-or operator and the Shell pipe-operator for moving data, where data flows in the correct direction for input but the opposite direction for output.
     3428Input and output use a uniform operator, ©|©, rather than separate operators, as in ©>>© and ©<<© for \CC.
     3429There is a weak similarity between the \CFA logical-or operator and the \Index{Shell pipe-operator} for moving data, where data flows in the correct direction for input but the opposite direction for output.
     3430
     3431For unformatter input, the common case is reading a sequence of values separated by whitespace, where the type of an input constant must match with the type of the input variable.
     3432\begin{cquote}
     3433\begin{lrbox}{\LstBox}
     3434\begin{cfa}[aboveskip=0pt,belowskip=0pt]
     3435int x;   double y   char z;
     3436\end{cfa}
     3437\end{lrbox}
     3438\begin{tabular}{@{}l@{\hspace{3em}}l@{}}
     3439\multicolumn{1}{@{}l@{}}{\usebox\LstBox} \\
     3440\multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}}        & \multicolumn{1}{c}{\textbf{\CC}}      \\
     3441\begin{cfa}[aboveskip=0pt,belowskip=0pt]
     3442sin | x | y | z;
     3443\end{cfa}
     3444&
     3445\begin{cfa}[aboveskip=0pt,belowskip=0pt]
     3446cin >> x >> y >> z;
     3447\end{cfa}
     3448\\
     3449\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
     3450®1® ®2.5® ®A®
     3451\end{cfa}
     3452&
     3453\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
     3454®1® ®2.5® ®A®
     3455\end{cfa}
     3456\end{tabular}
     3457\end{cquote}
     3458
    34113459
    34123460
    34133461\subsection{Implicit Separator}
    34143462
    3415 The \Index{implicit separator}\index{I/O!separator} character (space/blank) is a separator not a terminator.
     3463The \Index{implicit separator}\index{I/O!separator} character (space/blank) is a separator not a terminator for output.
    34163464The rules for implicitly adding the separator are:
    34173465\begin{enumerate}
     
    34413489
    34423490\item
    3443 A separator does not appear before a C string starting with the (extended) \Index*{ASCII}\index{ASCII!extended} characters: \lstinline[mathescape=off,basicstyle=\tt]@([{=$£¥¡¿«@
     3491{\lstset{language=CFA,deletedelim=**[is][]{¢}{¢}}
     3492A seperator does not appear before a C string starting with the (extended) \Index*{ASCII}\index{ASCII!extended} characters: \lstinline[basicstyle=\tt]@,.;!?)]}%¢»@
     3493\begin{cfa}[belowskip=0pt]
     3494sout | 1 | ", x" | 2 | ". x" | 3 | "; x" | 4 | "! x" | 5 | "? x" | 6 | "% x"
     3495                | 7 | "¢ x" | 8 | "» x" | 9 | ") x" | 10 | "] x" | 11 | "} x";
     3496\end{cfa}
     3497\begin{cfa}[basicstyle=\tt,showspaces=true,aboveskip=0pt,belowskip=0pt]
     34981®,® x 2®.® x 3®;® x 4®!® x 5®?® x 6®%® x 7§\color{red}\textcent§ x 8®»® x 9®)® x 10®]® x 11®}® x
     3499\end{cfa}}%
     3500where \lstinline[basicstyle=\tt]@»@ is a closing citation mark.
     3501
     3502\item
     3503A separator does not appear after a C string ending with the (extended) \Index*{ASCII}\index{ASCII!extended} characters: \lstinline[mathescape=off,basicstyle=\tt]@([{=$£¥¡¿«@
    34443504%$
    34453505\begin{cfa}[mathescape=off]
     
    34553515
    34563516\item
    3457 {\lstset{language=CFA,deletedelim=**[is][]{¢}{¢}}
    3458 A seperator does not appear after a C string ending with the (extended) \Index*{ASCII}\index{ASCII!extended} characters: \lstinline[basicstyle=\tt]@,.;!?)]}%¢»@
    3459 \begin{cfa}[belowskip=0pt]
    3460 sout | 1 | ", x" | 2 | ". x" | 3 | "; x" | 4 | "! x" | 5 | "? x" | 6 | "% x"
    3461                 | 7 | "¢ x" | 8 | "» x" | 9 | ") x" | 10 | "] x" | 11 | "} x";
    3462 \end{cfa}
    3463 \begin{cfa}[basicstyle=\tt,showspaces=true,aboveskip=0pt,belowskip=0pt]
    3464 1®,® x 2®.® x 3®;® x 4®!® x 5®?® x 6®%® x 7§\color{red}\textcent§ x 8®»® x 9®)® x 10®]® x 11®}® x
    3465 \end{cfa}}%
    3466 where \lstinline[basicstyle=\tt]@»@ is a closing citation mark.
    3467 
    3468 \item
    3469 A seperator does not appear before or after a C string begining/ending with the \Index*{ASCII} quote or whitespace characters: \lstinline[basicstyle=\tt,showspaces=true]@`'": \t\v\f\r\n@
     3517A seperator does not appear before/after a C string starting/ending with the \Index*{ASCII} quote or whitespace characters: \lstinline[basicstyle=\tt,showspaces=true]@`'": \t\v\f\r\n@
    34703518\begin{cfa}[belowskip=0pt]
    34713519sout | "x`" | 1 | "`x'" | 2 | "'x\"" | 3 | "\"x:" | 4 | ":x " | 5 | " x\t" | 6 | "\tx";
     
    34863534
    34873535
    3488 \subsection{Manipulator}
    3489 
    3490 The following \CC-style \Index{manipulator}s and routines control implicit seperation.
     3536\subsection{Separation Manipulators}
     3537
     3538The following \Index{manipulator}s control \Index{implicit output separation}.
     3539The effect of these manipulators is global for an output stream (except ©sepOn© and ©sepOff©).
    34913540\begin{enumerate}
    34923541\item
    3493 Routines \Indexc{sepSet}\index{manipulator!sepSet@©sepSet©} and \Indexc{sep}\index{manipulator!sep@©sep©}/\Indexc{sepGet}\index{manipulator!sepGet@©sepGet©} set and get the separator string.
     3542\Indexc{sepSet}\index{manipulator!sepSet@©sepSet©} and \Indexc{sep}\index{manipulator!sep@©sep©}/\Indexc{sepGet}\index{manipulator!sepGet@©sepGet©} set and get the separator string.
    34943543The separator string can be at most 16 characters including the ©'\0'© string terminator (15 printable characters).
    34953544\begin{cfa}[mathescape=off,belowskip=0pt]
    3496 sepSet( sout, ", $" );                                          §\C{// set separator from " " to ", \$"}§
     3545sepSet( sout, ", $" ); §\C{// set separator from " " to ", \$"}§
    34973546sout | 1 | 2 | 3 | " \"" | ®sep® | "\"";
    34983547\end{cfa}
     
    35033552%$
    35043553\begin{cfa}[belowskip=0pt]
    3505 sepSet( sout, " " );                                            §\C{// reset separator to " "}§
     3554sepSet( sout, " " ); §\C{// reset separator to " "}§
    35063555sout | 1 | 2 | 3 | " \"" | ®sepGet( sout )® | "\"";
    35073556\end{cfa}
     
    35113560©sepGet© can be used to store a separator and then restore it:
    35123561\begin{cfa}[belowskip=0pt]
    3513 char store[®sepSize®];                                          §\C{// sepSize is the maximum separator size}§
    3514 strcpy( store, sepGet( sout ) );                          §\C{// copy current separator}§
    3515 sepSet( sout, "_" );                                            §\C{// change separator to underscore}§
     3562char store[®sepSize®]; §\C{// sepSize is the maximum separator size}§
     3563strcpy( store, sepGet( sout ) ); §\C{// copy current separator}§
     3564sepSet( sout, "_" ); §\C{// change separator to underscore}§
    35163565sout | 1 | 2 | 3;
    35173566\end{cfa}
     
    35203569\end{cfa}
    35213570\begin{cfa}[belowskip=0pt]
    3522 sepSet( sout, store );                                          §\C{// change separator back to original}§
     3571sepSet( sout, store ); §\C{// change separator back to original}§
    35233572sout | 1 | 2 | 3;
    35243573\end{cfa}
     
    35283577
    35293578\item
    3530 Routine \Indexc{sepSetTuple}\index{manipulator!sepSetTuple@©sepSetTuple©} and \Indexc{sepTuple}\index{manipulator!sepTuple@©sepTuple©}/\Indexc{sepGetTuple}\index{manipulator!sepGetTuple@©sepGetTuple©} get and set the tuple separator-string.
     3579\Indexc{sepSetTuple}\index{manipulator!sepSetTuple@©sepSetTuple©} and \Indexc{sepTuple}\index{manipulator!sepTuple@©sepTuple©}/\Indexc{sepGetTuple}\index{manipulator!sepGetTuple@©sepGetTuple©} get and set the tuple separator-string.
    35313580The tuple separator-string can be at most 16 characters including the ©'\0'© string terminator (15 printable characters).
    35323581\begin{cfa}[belowskip=0pt]
    3533 sepSetTuple( sout, " " );                                       §\C{// set tuple separator from ", " to " "}§
     3582sepSetTuple( sout, " " ); §\C{// set tuple separator from ", " to " "}§
    35343583sout | t1 | t2 | " \"" | ®sepTuple® | "\"";
    35353584\end{cfa}
     
    35383587\end{cfa}
    35393588\begin{cfa}[belowskip=0pt]
    3540 sepSetTuple( sout, ", " );                                      §\C{// reset tuple separator to ", "}§
     3589sepSetTuple( sout, ", " ); §\C{// reset tuple separator to ", "}§
    35413590sout | t1 | t2 | " \"" | ®sepGetTuple( sout )® | "\"";
    35423591\end{cfa}
     
    35473596
    35483597\item
    3549 Manipulators \Indexc{sepDisable}\index{manipulator!sepDisable@©sepDisable©} and \Indexc{sepEnable}\index{manipulator!sepEnable@©sepEnable©} \emph{globally} toggle printing the separator, \ie the seperator is adjusted with respect to all subsequent printed items.
     3598\Indexc{sepDisable}\index{manipulator!sepDisable@©sepDisable©} and \Indexc{sepEnable}\index{manipulator!sepEnable@©sepEnable©} toggle printing the separator.
    35503599\begin{cfa}[belowskip=0pt]
    3551 sout | sepDisable | 1 | 2 | 3;                  §\C{// globally turn off implicit separator}§
     3600sout | sepDisable | 1 | 2 | 3; §\C{// turn off implicit separator}§
    35523601\end{cfa}
    35533602\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
     
    35553604\end{cfa}
    35563605\begin{cfa}[belowskip=0pt]
    3557 sout | sepEnable | 1 | 2 | 3;           §\C{// globally turn on implicit separator}§
     3606sout | sepEnable | 1 | 2 | 3; §\C{// turn on implicit separator}§
    35583607\end{cfa}
    35593608\begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
     
    35623611
    35633612\item
    3564 Manipulators \Indexc{sepOn}\index{manipulator!sepOn@©sepOn©} and \Indexc{sepOff}\index{manipulator!sepOff@©sepOff©} \emph{locally} toggle printing the separator, \ie the seperator is adjusted only with respect to the next printed item.
     3613\Indexc{sepOn}\index{manipulator!sepOn@©sepOn©} and \Indexc{sepOff}\index{manipulator!sepOff@©sepOff©} toggle printing the separator with respect to the next printed item, and then return to the global seperator setting.
    35653614\begin{cfa}[belowskip=0pt]
    3566 sout | 1 | sepOff | 2 | 3;                      §\C{// locally turn off implicit separator
     3615sout | 1 | sepOff | 2 | 3; §\C{// turn off implicit separator for the next item
    35673616\end{cfa}
    35683617\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
     
    35703619\end{cfa}
    35713620\begin{cfa}[belowskip=0pt]
    3572 sout | sepDisable | 1 | sepOn | 2 | 3; §\C{// locally turn on implicit separator
     3621sout | sepDisable | 1 | sepOn | 2 | 3; §\C{// turn on implicit separator for the next item
    35733622\end{cfa}
    35743623\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
     
    35773626The tuple separator also responses to being turned on and off.
    35783627\begin{cfa}[belowskip=0pt]
    3579 sout | t1 | sepOff | t2;                                §\C{// locally turn on/off implicit separator}§
     3628sout | t1 | sepOff | t2; §\C{// locally turn on/off implicit separator}§
    35803629\end{cfa}
    35813630\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
     
    35853634use ©sep© to accomplish this functionality.
    35863635\begin{cfa}[belowskip=0pt]
    3587 sout | sepOn | 1 | 2 | 3 | sepOn;       §\C{// sepOn does nothing at start/end of line}§
     3636sout | sepOn | 1 | 2 | 3 | sepOn; §\C{// sepOn does nothing at start/end of line}§
    35883637\end{cfa}
    35893638\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
     
    35913640\end{cfa}
    35923641\begin{cfa}[belowskip=0pt]
    3593 sout | sep | 1 | 2 | 3 | sep ;          §\C{// use sep to print separator at start/end of line}§
     3642sout | sep | 1 | 2 | 3 | sep ; §\C{// use sep to print separator at start/end of line}§
    35943643\end{cfa}
    35953644\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    35963645® ®1 2 3® ®
     3646\end{cfa}
     3647\end{enumerate}
     3648
     3649
     3650\subsection{Newline Manipulators}
     3651
     3652The following \Index{manipulator} controls \Index{newline separation} for input and output.
     3653
     3654For input:
     3655\begin{enumerate}[parsep=0pt]
     3656\item
     3657\Indexc{nl}\index{manipulator!nl@©nl©} scans characters until the next newline character, i.e., ignore the remaining characters in the line.
     3658\item
     3659\Indexc{nlOn}\index{manipulator!nlOn@©nlOn©} reads the newline character, when reading single characters.
     3660\item
     3661\Indexc{nlOff}\index{manipulator!nlOff@©nlOff©} does \emph{not} read the newline character, when reading single characters.
     3662\end{enumerate}
     3663For example, in:
     3664\begin{cfa}
     3665sin | i | ®nl® | j;
     36661 ®2®
     36673
     3668\end{cfa}
     3669variable ©i© is assigned 1, the 2 is skipped, and variable ©j© is assigned 3.
     3670
     3671For output:
     3672\begin{enumerate}[parsep=0pt]
     3673\item
     3674\Indexc{nl}\index{manipulator!nl@©nl©} inserts a newline.
     3675\begin{cfa}
     3676sout | nl; §\C{// only print newline}§
     3677sout | 2; §\C{// implicit newline}§
     3678sout | 3 | nl | 4 | nl; §\C{// terminating nl merged with implicit newline}§
     3679sout | 5 | nl | nl; §\C{// again terminating nl merged with implicit newline}§
     3680sout | 6; §\C{// implicit newline}§
     3681
     36822
     36833
     36844
     36855
     3686
     36876
     3688\end{cfa}
     3689Note, a terminating ©nl© is merged (overrides) with the implicit newline at the end of the ©sout© expression, otherwise it is impossible to to print a single newline
     3690\item
     3691\Indexc{nlOn}\index{manipulator!nlOn@©nlOn©} implicitly prints a newline at the end of each output expression.
     3692\item
     3693\Indexc{nlOff}\index{manipulator!nlOff@©nlOff©} does \emph{not} implicitly print a newline at the end of each output expression.
     3694\end{enumerate}
     3695
     3696
     3697\subsection{Output Value Manipulators}
     3698
     3699The following \Index{manipulator}s control formatting of output values (printing), and only affect the format of the argument.
     3700\begin{enumerate}
     3701\item
     3702\Indexc{bin}( integer )\index{manipulator!bin@©bin©} print value in base 2 preceded by ©0b©/©0B©.
     3703\begin{cfa}[belowskip=0pt]
     3704sout | bin( 0 ) | bin( 27HH ) | bin( 27H ) | bin( 27 ) | bin( 27L );
     37050b0 0b11011 0b11011 0b11011 0b11011
     3706sout | bin( -27HH ) | bin( -27H ) | bin( -27 ) | bin( -27L );
     37070b11100101 0b1111111111100101 0b11111111111111111111111111100101 0b(58 1s)100101
     3708\end{cfa}
     3709
     3710\item
     3711\Indexc{oct}( integer )\index{manipulator!oct@©oct©} print value in base 8 preceded by ©0©.
     3712\begin{cfa}[belowskip=0pt]
     3713sout | oct( 0 ) | oct( 27HH ) | oct( 27H ) | oct( 27 ) | oct( 27L );
     37140 033 033 033 033
     3715sout | oct( -27HH ) | oct( -27H ) | oct( -27 ) | oct( -27L );
     37160345 0177745 037777777745 01777777777777777777745
     3717\end{cfa}
     3718Note, octal 0 is \emph{not} preceded by ©0© to prevent confusion.
     3719
     3720\item
     3721\Indexc{hex}( integer / floating-point )\index{manipulator!hex@©hex©} print value in base 16 preceded by ©0x©/©0X©.
     3722\begin{cfa}[belowskip=0pt]
     3723sout | hex( 0 ) | hex( 27HH ) | hex( 27H ) | hex( 27 ) | hex( 27L );
     37240 0x1b 0x1b 0x1b 0x1b
     3725sout | hex( -27HH ) | hex( -27H ) | hex( -27 ) | hex( -27L );
     37260xe5 0xffe5 0xffffffe5 0xffffffffffffffe5
     3727
     3728sout | hex( 0.0 ) | hex( 27.5F ) | hex( 27.5 ) | hex( 27.5L );
     37290x0.p+0 0x1.b8p+4 0x1.b8p+4 0xd.cp+1
     3730sout | hex( -27.5F ) | hex( -27.5 ) | hex( -27.5L );
     3731-0x1.b8p+4 -0x1.b8p+4 -0xd.cp+1
     3732\end{cfa}
     3733
     3734\item
     3735\Indexc{sci}( floating-point )\index{manipulator!sci@©sci©} print value in scientific notation with exponent.
     3736Default is 6 digits of precision.
     3737\begin{cfa}[belowskip=0pt]
     3738sout | sci( 0.0 ) | sci( 27.5 ) | sci( -27.5 );
     37390.000000e+00 2.750000e+01 -2.750000e+01
     3740\end{cfa}
     3741
     3742\item
     3743\Indexc{upcase}( bin / hex / floating-point )\index{manipulator!upcase@©upcase©} print letters in a value in upper case. Lower case is the default.
     3744\begin{cfa}[belowskip=0pt]
     3745sout | upcase( bin( 27 ) ) | upcase( hex( 27 ) ) | upcase( 27.5e-10 ) | upcase( hex( 27.5 ) );
     37460®B®11011 0®X®1®B® 2.75®E®-09 0®X®1.®B®8®P®+4
     3747\end{cfa}
     3748
     3749\item
     3750\Indexc{nobase}( integer )\index{manipulator!nobase@©nobase©} do not precede ©bin©, ©oct©, ©hex© with ©0b©/©0B©, ©0©, or ©0x©/©0X©. Printing the base is the default.
     3751\begin{cfa}[belowskip=0pt]
     3752sout | nobase( bin( 27 ) ) | nobase( oct( 27 ) ) | nobase( hex( 27 ) );
     375311011 33 1b
     3754\end{cfa}
     3755
     3756\item
     3757\Indexc{nodp}( floating-point )\index{manipulator!nodp@©nodp©} do not print a decimal point if there are no fractional digits.
     3758Printing a decimal point is the default, if there are no fractional digits.
     3759\begin{cfa}[belowskip=0pt]
     3760sout | 0. | nodp( 0. ) | 27.0 | nodp( 27.0 ) | nodp( 27.5 );
     37610.0 ®0® 27.0 ®27® 27.5
     3762\end{cfa}
     3763
     3764\item
     3765\Indexc{sign}( integer / floating-point )\index{manipulator!sign@©sign©} prefix with plus or minus sign (©+© or ©-©). Only printing the minus sign is the default.
     3766\begin{cfa}[belowskip=0pt]
     3767sout | sign( 27 ) | sign( -27 ) | sign( 27. ) | sign( -27. ) | sign( 27.5 ) | sign( -27.5 );
     3768®+®27 -27 ®+®27.0 -27.0 ®+®27.5 -27.5
     3769\end{cfa}
     3770
     3771\item
     3772\Indexc{wd}©( unsigned char minimum, T val )©\index{manipulator!wd@©wd©}, ©wd( unsigned char minimum, unsigned char precision, T val )©
     3773For all types, ©minimum© is the minimum number of printed characters.
     3774If the value is shorter than the minimum, it is padded on the right with spaces.
     3775\begin{cfa}[belowskip=0pt]
     3776sout | wd( 4, 34) | wd( 3, 34 ) | wd( 2, 34 );
     3777sout | wd( 10, 4.) | wd( 9, 4. ) | wd( 8, 4. );
     3778sout | wd( 4, "ab" ) | wd( 3, "ab" ) | wd( 2, "ab" );
     3779\end{cfa}
     3780\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
     3781®  ®34 ® ®34 34
     3782®  ®4.000000 ® ®4.000000 4.000000
     3783®  ®ab ® ®ab ab
     3784    ab    ab ab
     3785\end{cfa}
     3786If the value is larger, it is printed without truncation, ignoring the ©minimum©.
     3787\begin{cfa}[belowskip=0pt]
     3788sout | wd( 4, 34567 ) | wd( 3, 34567 ) | wd( 2, 34567 );
     3789sout | wd( 4, 3456. ) | wd( 3, 3456. ) | wd( 2, 3456. );
     3790sout | wd( 4, "abcde" ) | wd( 3, "abcde" ) | wd( 2,"abcde" );
     3791\end{cfa}
     3792\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
     37933456®7® 345®67® 34®567®
     37943456®.® 345®6.® 34®56.®
     3795abcd®e® abc®de® ab®cde®
     3796\end{cfa}
     3797
     3798For integer types, ©precision© is the minimum number of printed digits.
     3799If the value is shorter, it is padded on the left with leading zeros.
     3800\begin{cfa}[belowskip=0pt]
     3801sout | wd( 4,3, 34 ) | wd( 8,4, 34 ) | wd( 10,10, 34 );
     3802\end{cfa}
     3803\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
     3804 ®0®34     ®00®34 ®00000000®34
     3805\end{cfa}
     3806If the value is larger, it is printed without truncation, ignoring the ©precision©.
     3807\begin{cfa}[belowskip=0pt]
     3808sout | wd( 4,1, 3456 ) | wd( 8,2, 3456 ) | wd( 10,3, 3456 );
     3809\end{cfa}
     3810\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
     38113456     3456       3456
     3812\end{cfa}
     3813If ©precision© is 0, nothing is printed for zero.
     3814If ©precision© is greater than the minimum, it becomes the minimum.
     3815\begin{cfa}[belowskip=0pt]
     3816sout | wd( 4,0, 0 ) | wd( 3,10, 34 );
     3817\end{cfa}
     3818\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
     3819®    ® ®00000000®34
     3820\end{cfa}
     3821For floating-point types, ©precision© is the minimum number of digits after the decimal point.
     3822\begin{cfa}[belowskip=0pt]
     3823sout | wd( 6,3, 27.5 ) | wd( 8,1, 27.5 ) | wd( 8,0, 27.5 ) | wd( 3,8, 27.5 );
     3824\end{cfa}
     3825\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
     382627.®500®     27.®5®      28. 27.®50000000®
     3827\end{cfa}
     3828For the C-string type, ©precision© is the maximum number of printed characters, so the string is truncared if it exceeds the maximum.
     3829\begin{cfa}[belowskip=0pt]
     3830sout | wd( 6,8, "abcd" ) | wd( 6,8, "abcdefghijk" ) | wd( 6,3, "abcd" );
     3831\end{cfa}
     3832\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
     3833  abcd abcdefgh    abc
     3834\end{cfa}
     3835
     3836\item
     3837\Indexc{ws( unsigned char minimum, unsigned char significant, floating-point )}\index{manipulator!ws@©ws©}
     3838For floating-point type, ©minimum© is the same as for manipulator ©wd©, but ©significant© is the maximum number of significant digits to be printed for both the integer and fractions (versus only the fraction for ©wd©).
     3839If a value's significant digits is greater than ©significant©, the last significant digit is rounded up.
     3840\begin{cfa}[belowskip=0pt]
     3841sout | ws(6,6, 234.567) | ws(6,5, 234.567) | ws(6,4, 234.567) | ws(6,3, 234.567);
     3842\end{cfa}
     3843\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
     3844234.567 234.5®7®  234.®6®    23®5®
     3845\end{cfa}
     3846If a value's magnitude is greater than ©significant©, the value is printed in scientific notation with the specified number of significant digits.
     3847\begin{cfa}[belowskip=0pt]
     3848sout | ws(6,6, 234567.) | ws(6,5, 234567.) | ws(6,4, 234567.) | ws(6,3, 234567.);
     3849\end{cfa}
     3850\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
     3851234567. 2.3457®e+05® 2.346®e+05® 2.35®e+05®
     3852\end{cfa}
     3853If ©significant© is greater than ©minimum©, it defines the number of printed characters.
     3854\begin{cfa}[belowskip=0pt]
     3855sout | ws(3,6, 234567.) | ws(4,6, 234567.) | ws(5,6, 234567.) | ws(6,6, 234567.);
     3856\end{cfa}
     3857\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
     3858234567. 234567. 234567. 234567.
     3859\end{cfa}
     3860
     3861\item
     3862\Indexc{left}( field-width )\index{manipulator!left@©left©} left justify within the given field.
     3863\begin{cfa}[belowskip=0pt]
     3864sout | left(wd(4, 27)) | left(wd(10, 27.)) | left(wd(10, 27.5)) | left(wd(4,3, 27)) | left(wd(10,3, 27.5));
     3865\end{cfa}
     3866\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
     386727®  ® 27.000000  27.500000  027  27.500®    ®
     3868\end{cfa}
     3869
     3870\item
     3871\Indexc{pad0}( field-width )\index{manipulator!pad0@©pad0©} left pad with zeroes (0).
     3872\begin{cfa}[belowskip=0pt]
     3873sout | pad0( wd( 4, 27 ) ) | pad0( wd( 4,3, 27 ) ) | pad0( wd( 8,3, 27.5 ) );
     3874®00®27  ®0®27 ®00®27.500
    35973875\end{cfa}
    35983876\end{enumerate}
     
    36553933
    36563934
     3935\subsection{Input Value Manipulators}
     3936
     3937The format of numeric input values in the same as C constants without a trailing type suffix, as the input value-type is denoted by the input variable.
     3938For ©_Bool© type, the constants are ©true© and ©false©.
     3939For integral types, any number of digits, optionally preceded by a sign (©+© or ©-©), where a
     3940\begin{itemize}
     3941\item
     3942©1©-©9© prefix introduces a decimal value (©0©-©9©),
     3943\item
     3944©0© prefix introduces an octal value (©0©-©7©), and
     3945\item
     3946©0x© or ©0X© prefix introduces a hexadecimal value (©0©-©f©) with lower or upper case letters.
     3947\end{itemize}
     3948For floating-point types, any number of decimal digits, optionally preceded by a sign (©+© or ©-©), optionally containing a decimal point, and optionally followed by an exponent, ©e© or ©E©, with signed (optional) decimal digits.
     3949Floating-point values can also be written in hexadecimal format preceded by ©0x© or ©0X© with hexadecimal digits and exponent denoted by ©p© or ©P©.
     3950
     3951For the C-string type, the input values are \emph{not} the same as C-string constants, \ie double quotes bracketing arbitrary text with escape sequences.
     3952Instead, the next sequence of non-whitespace characters are read, and the input sequence is terminated with delimiter ©'\0'©.
     3953The string variable \emph{must} be large enough to contain the input sequence.
     3954
     3955The following \Index{manipulator}s control formatting of input values (reading), and only affect the format of the argument.
     3956
     3957\begin{enumerate}
     3958\item
     3959\Indexc{skip( const char * pattern )}\index{manipulator!skip@©skip©} / ©skip( unsigned int length )© / ©const char * pattern©
     3960The argument defines a ©pattern© or ©length©.
     3961The ©pattern© is composed of white-space and non-white-space characters, where \emph{any} white-space character matches 0 or more input white-space characters (hence, consecutive white-space characters in the pattern are combined), and each non-white-space character matches exactly with an input character.
     3962The ©length© is composed of the next $N$ characters, including the newline character.
     3963If the match successes, the input characters are discarded, and input continues with the next character.
     3964If the match fails, the input characters are left unread.
     3965\begin{cfa}[belowskip=0pt]
     3966char sk[$\,$] = "abc";
     3967sin | "abc " | skip( sk ) | skip( 5 ); // match input sequence
     3968\end{cfa}
     3969\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
     3970®abc   ®
     3971®abc  ®
     3972®xx®
     3973\end{cfa}
     3974
     3975\item
     3976\Indexc{wdi}©( unsigned int maximum, T & val )©\index{manipulator!wdi@©wdi©}
     3977For all types except ©char©, ©maximum© is the maximum number of characters read for the current operation.
     3978\begin{cfa}[belowskip=0pt]
     3979char s[10];   int i;   double d;   
     3980sin | wdi( 4, s ) | wdi( 3, i ) | wdi( 8, d );  // c == "abcd", i == 123, d == 3.456E+2
     3981\end{cfa}
     3982\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
     3983®abcd1233.456E+2®
     3984\end{cfa}
     3985Note, input ©wdi© cannot be overloaded with output ©wd© because both have the same parameters but return different types.
     3986Currently, \CFA cannot distinguish between these two manipulators in the middle of an ©sout©/©sin© expression based on return type.
     3987
     3988\item
     3989\Indexc{ignore( T & val )}\index{manipulator!ignore@©ignore©}
     3990For all types, the data is read from the stream depending on the argument type but ignored, \ie it is not stored in the argument.
     3991\begin{cfa}[belowskip=0pt]
     3992double d;
     3993sin | ignore( d );  // d is unchanged
     3994\end{cfa}
     3995\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
     3996®  -75.35e-4® 25
     3997\end{cfa}
     3998
     3999\item
     4000\Indexc{incl( const char * scanset, char * s )}\index{manipulator!incl@©incl©}
     4001For the C-string type, the argument defines a ©scanset© that matches any number of characters \emph{in} the set.
     4002Matching characters are read into the C string and null terminated.
     4003\begin{cfa}[belowskip=0pt]
     4004char s[10];
     4005sin | incl( "abc", s );
     4006\end{cfa}
     4007\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
     4008®bca®xyz
     4009\end{cfa}
     4010
     4011\item
     4012\Indexc{excl( const char * scanset, char * s )}\index{manipulator!excl@©excl©}
     4013For the C-string type, the argument defines a ©scanset© that matches any number of characters \emph{not in} the set.
     4014Non-matching characters are read into the C string and null terminated.
     4015\begin{cfa}[belowskip=0pt]
     4016char s[10];
     4017sin | excl( "abc", s );
     4018\end{cfa}
     4019\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
     4020®xyz®bca
     4021\end{cfa}
     4022\end{enumerate}
     4023
     4024
    36574025\section{Types}
    36584026
     
    40224390\begin{itemize}
    40234391\item
    4024 preventing having to determine or write long generic types,
    4025 \item
    4026 ensure secondary variables, related to a primary variable, always have the same type.
     4392not determining or writing long generic types,
     4393\item
     4394ensuring secondary variables, related to a primary variable, always have the same type.
    40274395\end{itemize}
    40284396
     
    40464414There is also the conundrum in type inferencing of when to \emph{\Index{brand}} a type.
    40474415That is, when is the type of the variable more important than the type of its initialization expression.
    4048 For example, if a change is made in an initialization expression, it can cause significant cascading type changes and/or errors.
     4416For example, if a change is made in an initialization expression, it can cause cascading type changes and/or errors.
    40494417At some point, a variable type needs to remain constant and the expression to be in error when it changes.
    40504418
     
    42794647
    42804648coroutine Fibonacci {
    4281         int fn;                                                         §\C{// used for communication}§
     4649        int fn; §\C{// used for communication}§
    42824650};
    42834651void ?{}( Fibonacci * this ) {
     
    42854653}
    42864654void main( Fibonacci * this ) {
    4287         int fn1, fn2;                                           §\C{// retained between resumes}§
    4288         this->fn = 0;                                           §\C{// case 0}§
     4655        int fn1, fn2; §\C{// retained between resumes}§
     4656        this->fn = 0; §\C{// case 0}§
    42894657        fn1 = this->fn;
    4290         suspend();                                                      §\C{// return to last resume}§
    4291 
    4292         this->fn = 1;                                           §\C{// case 1}§
     4658        suspend(); §\C{// return to last resume}§
     4659
     4660        this->fn = 1; §\C{// case 1}§
    42934661        fn2 = fn1;
    42944662        fn1 = this->fn;
    4295         suspend();                                                      §\C{// return to last resume}§
    4296 
    4297         for ( ;; ) {                                            §\C{// general case}§
     4663        suspend(); §\C{// return to last resume}§
     4664
     4665        for ( ;; ) { §\C{// general case}§
    42984666                this->fn = fn1 + fn2;
    42994667                fn2 = fn1;
    43004668                fn1 = this->fn;
    4301                 suspend();                                              §\C{// return to last resume}§
     4669                suspend(); §\C{// return to last resume}§
    43024670        } // for
    43034671}
    43044672int next( Fibonacci * this ) {
    4305         resume( this );                                         §\C{// transfer to last suspend}§
     4673        resume( this ); §\C{// transfer to last suspend}§
    43064674        return this->fn;
    43074675}
     
    58486216In \CFA, there are ambiguous cases with dereference and operator identifiers, \eg ©int *?*?()©, where the string ©*?*?© can be interpreted as:
    58496217\begin{cfa}
    5850 *?§\color{red}\textvisiblespace§*?              §\C{// dereference operator, dereference operator}§
    5851 *§\color{red}\textvisiblespace§?*?              §\C{// dereference, multiplication operator}§
     6218*?§\color{red}\textvisiblespace§*? §\C{// dereference operator, dereference operator}§
     6219*§\color{red}\textvisiblespace§?*? §\C{// dereference, multiplication operator}§
    58526220\end{cfa}
    58536221By default, the first interpretation is selected, which does not yield a meaningful parse.
     
    59016269\eg:
    59026270\begin{cfa}
    5903 x;                                                              §\C{// int x}§
    5904 *y;                                                             §\C{// int *y}§
    5905 f( p1, p2 );                                    §\C{// int f( int p1, int p2 );}§
    5906 g( p1, p2 ) int p1, p2;                 §\C{// int g( int p1, int p2 );}§
     6271x; §\C{// int x}§
     6272*y; §\C{// int *y}§
     6273f( p1, p2 ); §\C{// int f( int p1, int p2 );}§
     6274g( p1, p2 ) int p1, p2; §\C{// int g( int p1, int p2 );}§
    59076275\end{cfa}
    59086276\CFA continues to support K\&R routine definitions:
    59096277\begin{cfa}
    5910 f( a, b, c )                                    §\C{// default int return}§
    5911         int a, b; char c                        §\C{// K\&R parameter declarations}§
     6278f( a, b, c ) §\C{// default int return}§
     6279        int a, b; char c §\C{// K\&R parameter declarations}§
    59126280{
    59136281        ...
     
    59286296int rtn( int i );
    59296297int rtn( char c );
    5930 rtn( 'x' );                                             §\C{// programmer expects 2nd rtn to be called}§
     6298rtn( 'x' ); §\C{// programmer expects 2nd rtn to be called}§
    59316299\end{cfa}
    59326300\item[Rationale:] it is more intuitive for the call to ©rtn© to match the second version of definition of ©rtn© rather than the first.
     
    59506318\item[Change:] make string literals ©const©:
    59516319\begin{cfa}
    5952 char * p = "abc";                               §\C{// valid in C, deprecated in \CFA}§
    5953 char * q = expr ? "abc" : "de"; §\C{// valid in C, invalid in \CFA}§
     6320char * p = "abc"; §\C{// valid in C, deprecated in \CFA}§
     6321char * q = expr ? "abc" : "de"; §\C{// valid in C, invalid in \CFA}§
    59546322\end{cfa}
    59556323The type of a string literal is changed from ©[] char© to ©const [] char©.
     
    59586326\begin{cfa}
    59596327char * p = "abc";
    5960 p[0] = 'w';                                             §\C{// segment fault or change constant literal}§
     6328p[0] = 'w'; §\C{// segment fault or change constant literal}§
    59616329\end{cfa}
    59626330The same problem occurs when passing a string literal to a routine that changes its argument.
     
    59706338\item[Change:] remove \newterm{tentative definitions}, which only occurs at file scope:
    59716339\begin{cfa}
    5972 int i;                                                  §\C{// forward definition}§
    5973 int *j = ®&i®;                                  §\C{// forward reference, valid in C, invalid in \CFA}§
    5974 int i = 0;                                              §\C{// definition}§
     6340int i; §\C{// forward definition}§
     6341int *j = ®&i®; §\C{// forward reference, valid in C, invalid in \CFA}§
     6342int i = 0; §\C{// definition}§
    59756343\end{cfa}
    59766344is valid in C, and invalid in \CFA because duplicate overloaded object definitions at the same scope level are disallowed.
     
    59786346\begin{cfa}
    59796347struct X { int i; struct X *next; };
    5980 static struct X a;                              §\C{// forward definition}§
     6348static struct X a; §\C{// forward definition}§
    59816349static struct X b = { 0, ®&a® };§\C{// forward reference, valid in C, invalid in \CFA}§
    5982 static struct X a = { 1, &b };  §\C{// definition}§
     6350static struct X a = { 1, &b }; §\C{// definition}§
    59836351\end{cfa}
    59846352\item[Rationale:] avoids having different initialization rules for builtin types and user-defined types.
     
    59956363struct Person {
    59966364        enum ®Colour® { R, G, B };      §\C[7cm]{// nested type}§
    5997         struct Face {                           §\C{// nested type}§
    5998                 ®Colour® Eyes, Hair;    §\C{// type defined outside (1 level)}§
     6365        struct Face { §\C{// nested type}§
     6366                ®Colour® Eyes, Hair; §\C{// type defined outside (1 level)}§
    59996367        };
    6000         ®.Colour® shirt;                        §\C{// type defined outside (top level)}§
    6001         ®Colour® pants;                         §\C{// type defined same level}§
    6002         Face looks[10];                         §\C{// type defined same level}§
     6368        ®.Colour® shirt; §\C{// type defined outside (top level)}§
     6369        ®Colour® pants; §\C{// type defined same level}§
     6370        Face looks[10]; §\C{// type defined same level}§
    60036371};
    6004 ®Colour® c = R;                                 §\C{// type/enum defined same level}§
     6372®Colour® c = R; §\C{// type/enum defined same level}§
    60056373Person®.Colour® pc = Person®.®R;§\C{// type/enum defined inside}§
    6006 Person®.®Face pretty;                   §\C{// type defined inside}\CRT§
     6374Person®.®Face pretty; §\C{// type defined inside}\CRT§
    60076375\end{cfa}
    60086376In C, the name of the nested types belongs to the same scope as the name of the outermost enclosing structure, \ie the nested types are hoisted to the scope of the outer-most type, which is not useful and confusing.
     
    60216389\item[Difficulty of converting:] Semantic transformation. To make the struct type name visible in the scope of the enclosing struct, the struct tag could be declared in the scope of the enclosing struct, before the enclosing struct is defined. Example:
    60226390\begin{cfa}
    6023 struct Y;                                               §\C{// struct Y and struct X are at the same scope}§
     6391struct Y; §\C{// struct Y and struct X are at the same scope}§
    60246392struct X {
    60256393        struct Y { /* ... */ } y;
     
    60366404\begin{cfa}
    60376405void foo() {
    6038         int * b = malloc( sizeof(int) );        §\C{// implicitly convert void * to int *}§
    6039         char * c = b;                           §\C{// implicitly convert int * to void *, and then void * to char *}§
     6406        int * b = malloc( sizeof(int) ); §\C{// implicitly convert void * to int *}§
     6407        char * c = b; §\C{// implicitly convert int * to void *, and then void * to char *}§
    60406408}
    60416409\end{cfa}
     
    62986666\leavevmode
    62996667\begin{cfa}[aboveskip=0pt,belowskip=0pt]
    6300 forall( otype T | { int ?<?( T, T ); } )        §\C{// location}§
     6668forall( otype T | { int ?<?( T, T ); } ) §\C{// location}§
    63016669T * bsearch( T key, const T * arr, size_t dim );§\indexc{bsearch}§
    63026670
    6303 forall( otype T | { int ?<?( T, T ); } )        §\C{// position}§
     6671forall( otype T | { int ?<?( T, T ); } ) §\C{// position}§
    63046672unsigned int bsearch( T key, const T * arr, size_t dim );
    63056673
     
    63086676
    63096677forall( otype E | { int ?<?( E, E ); } ) {
    6310         E * bsearch( E key, const E * vals, size_t dim );§\indexc{bsearch}§     §\C{// location}§
     6678        E * bsearch( E key, const E * vals, size_t dim );§\indexc{bsearch}§ §\C{// location}§
    63116679        size_t bsearch( E key, const E * vals, size_t dim );§\C{// position}§
    63126680        E * bsearchl( E key, const E * vals, size_t dim );§\indexc{bsearchl}§
     
    63566724void srandom( unsigned int seed );§\indexc{srandom}§
    63576725char random( void );§\indexc{random}§
    6358 char random( char u );                                          §\C{// [0,u)}§
    6359 char random( char l, char u );                          §\C{// [l,u)}§
     6726char random( char u ); §\C{// [0,u)}§
     6727char random( char l, char u ); §\C{// [l,u)}§
    63606728int random( void );
    6361 int random( int u );                                            §\C{// [0,u)}§
    6362 int random( int l, int u );                                     §\C{// [l,u)}§
     6729int random( int u ); §\C{// [0,u)}§
     6730int random( int l, int u ); §\C{// [l,u)}§
    63636731unsigned int random( void );
    6364 unsigned int random( unsigned int u );          §\C{// [0,u)}§
     6732unsigned int random( unsigned int u ); §\C{// [0,u)}§
    63656733unsigned int random( unsigned int l, unsigned int u ); §\C{// [l,u)}§
    63666734long int random( void );
    6367 long int random( long int u );                          §\C{// [0,u)}§
    6368 long int random( long int l, long int u );      §\C{// [l,u)}§
     6735long int random( long int u ); §\C{// [0,u)}§
     6736long int random( long int l, long int u ); §\C{// [l,u)}§
    63696737unsigned long int random( void );
    63706738unsigned long int random( unsigned long int u ); §\C{// [0,u)}§
     
    64176785[ int, long double ] remquo( long double, long double );
    64186786
    6419 float div( float, float, int * );§\indexc{div}§ §\C{// alternative name for remquo}§
     6787float div( float, float, int * );§\indexc{div}§ §\C{// alternative name for remquo}§
    64206788double div( double, double, int * );
    64216789long double div( long double, long double, int * );
     
    65736941long double atan2( long double, long double );
    65746942
    6575 float atan( float, float );                                     §\C{// alternative name for atan2}§
     6943float atan( float, float ); §\C{// alternative name for atan2}§
    65766944double atan( double, double );§\indexc{atan}§
    65776945long double atan( long double, long double );
     
    67647132\begin{cfa}[aboveskip=0pt,belowskip=0pt]
    67657133struct Duration {
    6766         int64_t tv;                                                     §\C{// nanoseconds}§
     7134        int64_t tv; §\C{// nanoseconds}§
    67677135};
    67687136
     
    68947262\begin{cfa}[aboveskip=0pt,belowskip=0pt]
    68957263struct Time {
    6896         uint64_t tv;                                            §\C{// nanoseconds since UNIX epoch}§
     7264        uint64_t tv; §\C{// nanoseconds since UNIX epoch}§
    68977265};
    68987266
     
    69657333\begin{cfa}[aboveskip=0pt,belowskip=0pt]
    69667334struct Clock {
    6967         Duration offset;                                        §\C{// for virtual clock: contains offset from real-time}§
    6968         int clocktype;                                          §\C{// implementation only -1 (virtual), CLOCK\_REALTIME}§
     7335        Duration offset; §\C{// for virtual clock: contains offset from real-time}§
     7336        int clocktype; §\C{// implementation only -1 (virtual), CLOCK\_REALTIME}§
    69697337};
    69707338
     
    69747342void ?{}( Clock & clk, Duration adj );
    69757343
    6976 Duration getResNsec();                                  §\C{// with nanoseconds}§
    6977 Duration getRes();                                              §\C{// without nanoseconds}§
    6978 
    6979 Time getTimeNsec();                                             §\C{// with nanoseconds}§
    6980 Time getTime();                                                 §\C{// without nanoseconds}§
     7344Duration getResNsec(); §\C{// with nanoseconds}§
     7345Duration getRes(); §\C{// without nanoseconds}§
     7346
     7347Time getTimeNsec(); §\C{// with nanoseconds}§
     7348Time getTime(); §\C{// without nanoseconds}§
    69817349Time getTime( Clock & clk );
    69827350Time ?()( Clock & clk );
     
    69947362
    69957363\begin{cfa}
    6996 void ?{}( Int * this );                                 §\C{// constructor/destructor}§
     7364void ?{}( Int * this ); §\C{// constructor/destructor}§
    69977365void ?{}( Int * this, Int init );
    69987366void ?{}( Int * this, zero_t );
     
    70037371void ^?{}( Int * this );
    70047372
    7005 Int ?=?( Int * lhs, Int rhs );                  §\C{// assignment}§
     7373Int ?=?( Int * lhs, Int rhs ); §\C{// assignment}§
    70067374Int ?=?( Int * lhs, long int rhs );
    70077375Int ?=?( Int * lhs, unsigned long int rhs );
     
    70207388unsigned long int narrow( Int val );
    70217389
    7022 int ?==?( Int oper1, Int oper2 );               §\C{// comparison}§
     7390int ?==?( Int oper1, Int oper2 ); §\C{// comparison}§
    70237391int ?==?( Int oper1, long int oper2 );
    70247392int ?==?( long int oper2, Int oper1 );
     
    70567424int ?>=?( unsigned long int oper1, Int oper2 );
    70577425
    7058 Int +?( Int oper );                                             §\C{// arithmetic}§
     7426Int +?( Int oper ); §\C{// arithmetic}§
    70597427Int -?( Int oper );
    70607428Int ~?( Int oper );
     
    71387506Int ?>>=?( Int * lhs, mp_bitcnt_t shift );
    71397507
    7140 Int abs( Int oper );                                    §\C{// number functions}§
     7508Int abs( Int oper ); §\C{// number functions}§
    71417509Int fact( unsigned long int N );
    71427510Int gcd( Int oper1, Int oper2 );
     
    72497617// implementation
    72507618struct Rational {§\indexc{Rational}§
    7251         long int numerator, denominator;        §\C{// invariant: denominator > 0}§
     7619        long int numerator, denominator; §\C{// invariant: denominator > 0}§
    72527620}; // Rational
    72537621
    7254 Rational rational();                                    §\C{// constructors}§
     7622Rational rational(); §\C{// constructors}§
    72557623Rational rational( long int n );
    72567624Rational rational( long int n, long int d );
     
    72587626void ?{}( Rational * r, one_t );
    72597627
    7260 long int numerator( Rational r );               §\C{// numerator/denominator getter/setter}§
     7628long int numerator( Rational r ); §\C{// numerator/denominator getter/setter}§
    72617629long int numerator( Rational r, long int n );
    72627630long int denominator( Rational r );
    72637631long int denominator( Rational r, long int d );
    72647632
    7265 int ?==?( Rational l, Rational r );             §\C{// comparison}§
     7633int ?==?( Rational l, Rational r ); §\C{// comparison}§
    72667634int ?!=?( Rational l, Rational r );
    72677635int ?<?( Rational l, Rational r );
     
    72707638int ?>=?( Rational l, Rational r );
    72717639
    7272 Rational -?( Rational r );                              §\C{// arithmetic}§
     7640Rational -?( Rational r ); §\C{// arithmetic}§
    72737641Rational ?+?( Rational l, Rational r );
    72747642Rational ?-?( Rational l, Rational r );
     
    72767644Rational ?/?( Rational l, Rational r );
    72777645
    7278 double widen( Rational r );                             §\C{// conversion}§
     7646double widen( Rational r ); §\C{// conversion}§
    72797647Rational narrow( double f, long int md );
    72807648
  • libcfa/src/concurrency/coroutine.hfa

    r18e683b rc1ea11b  
    1010// Created On       : Mon Nov 28 12:27:26 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Mar 30 18:23:45 2018
    13 // Update Count     : 8
     12// Last Modified On : Fri Jun 21 17:49:39 2019
     13// Update Count     : 9
    1414//
    1515
     
    5353forall(dtype T | is_coroutine(T))
    5454void prime(T & cor);
     55
     56static inline struct coroutine_desc * active_coroutine() { return TL_GET( this_thread )->curr_cor; }
    5557
    5658//-----------------------------------------------------------------------------
  • libcfa/src/concurrency/invoke.h

    r18e683b rc1ea11b  
    1010// Created On       : Tue Jan 17 12:27:26 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat May 19 08:23:21 2018
    13 // Update Count     : 31
     12// Last Modified On : Sat Jun 22 18:19:13 2019
     13// Update Count     : 40
    1414//
    1515
     
    4646        #ifdef __cforall
    4747        extern "Cforall" {
    48                 static inline struct thread_desc             * & get_next( struct thread_desc             & this );
    49                 static inline struct __condition_criterion_t * & get_next( struct __condition_criterion_t & this );
     48                static inline struct thread_desc             *& get_next( struct thread_desc             & this );
     49                static inline struct __condition_criterion_t *& get_next( struct __condition_criterion_t & this );
    5050
    5151                extern thread_local struct KernelThreadData {
     
    199199        #ifdef __cforall
    200200        extern "Cforall" {
    201                 static inline struct coroutine_desc * active_coroutine() { return TL_GET( this_thread )->curr_cor; }
    202                 static inline struct thread_desc    * active_thread   () { return TL_GET( this_thread    ); }
    203                 static inline struct processor      * active_processor() { return TL_GET( this_processor ); } // UNSAFE
    204 
    205                 static inline thread_desc * & get_next( thread_desc & this ) {
     201                static inline thread_desc *& get_next( thread_desc & this ) {
    206202                        return this.next;
    207203                }
     
    210206                        return this.node.[next, prev];
    211207                }
    212 
    213                 static inline struct __condition_criterion_t * & get_next( struct __condition_criterion_t & this );
    214208
    215209                static inline void ?{}(__monitor_group_t & this) {
  • libcfa/src/concurrency/kernel.cfa

    r18e683b rc1ea11b  
    1010// Created On       : Tue Jan 17 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Apr  9 16:11:46 2018
    13 // Update Count     : 24
     12// Last Modified On : Thu Jun 20 17:21:23 2019
     13// Update Count     : 25
    1414//
    1515
     
    907907void doregister( cluster * cltr, thread_desc & thrd ) {
    908908        lock      (cltr->thread_list_lock __cfaabi_dbg_ctx2);
     909        cltr->nthreads += 1;
    909910        push_front(cltr->threads, thrd);
    910911        unlock    (cltr->thread_list_lock);
     
    914915        lock  (cltr->thread_list_lock __cfaabi_dbg_ctx2);
    915916        remove(cltr->threads, thrd );
     917        cltr->nthreads -= 1;
    916918        unlock(cltr->thread_list_lock);
    917919}
     
    919921void doregister( cluster * cltr, processor * proc ) {
    920922        lock      (cltr->proc_list_lock __cfaabi_dbg_ctx2);
     923        cltr->nprocessors += 1;
    921924        push_front(cltr->procs, *proc);
    922925        unlock    (cltr->proc_list_lock);
     
    926929        lock  (cltr->proc_list_lock __cfaabi_dbg_ctx2);
    927930        remove(cltr->procs, *proc );
     931        cltr->nprocessors -= 1;
    928932        unlock(cltr->proc_list_lock);
    929933}
  • libcfa/src/concurrency/kernel.hfa

    r18e683b rc1ea11b  
    1010// Created On       : Tue Jan 17 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Apr 10 14:46:49 2018
    13 // Update Count     : 10
     12// Last Modified On : Sat Jun 22 11:39:17 2019
     13// Update Count     : 16
    1414//
    1515
     
    9191        this.lock = NULL;
    9292}
    93 static inline void ^?{}(FinishAction & this) {}
     93static inline void ^?{}(FinishAction &) {}
    9494
    9595// Processor
     
    176176        __dllist_t(struct processor) procs;
    177177        __dllist_t(struct processor) idles;
    178 
    179         // List of processors
     178        unsigned int nprocessors;
     179
     180        // List of threads
    180181        __spinlock_t thread_list_lock;
    181182        __dllist_t(struct thread_desc) threads;
     183        unsigned int nthreads;
    182184
    183185        // Link lists fields
     
    200202}
    201203
     204static inline struct processor * active_processor() { return TL_GET( this_processor ); } // UNSAFE
     205static inline struct cluster   * active_cluster  () { return TL_GET( this_processor )->cltr; }
     206
    202207// Local Variables: //
    203208// mode: c //
  • libcfa/src/concurrency/thread.hfa

    r18e683b rc1ea11b  
    1010// Created On       : Tue Jan 17 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar 29 14:07:11 2018
    13 // Update Count     : 4
     12// Last Modified On : Fri Jun 21 17:51:33 2019
     13// Update Count     : 5
    1414//
    1515
     
    9191void yield( unsigned times );
    9292
     93static inline struct thread_desc * active_thread () { return TL_GET( this_thread ); }
     94
    9395// Local Variables: //
    9496// mode: c //
  • src/ResolvExpr/Cost.h

    r18e683b rc1ea11b  
    1010// Created On       : Sun May 17 09:39:50 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Apr 29 18:33:44 2019
    13 // Update Count     : 49
     12// Last Modified On : Fri Jun 21 11:39:13 2019
     13// Update Count     : 63
    1414//
    1515
     
    2121
    2222namespace ResolvExpr {
    23 #if 0
    24 
    25         //*************************** OLD ***************************
    26 
    27         class Cost {
    28           private:
    29                 Cost( int unsafeCost, int polyCost, int safeCost, int signCost,
    30                           int varCost, int specCost, int referenceCost );
    31           public:
    32                 Cost & incUnsafe( int inc = 1 );
    33                 Cost & incPoly( int inc = 1 );
    34                 Cost & incSafe( int inc = 1 );
    35                 Cost & incSign( int inc = 1 );
    36                 Cost & incVar( int inc = 1 );
    37                 Cost & decSpec( int inc = 1 );
    38                 Cost & incReference( int inc = 1 );
    39 
    40                 int get_unsafeCost() const { return unsafeCost; }
    41                 int get_polyCost() const { return polyCost; }
    42                 int get_safeCost() const { return safeCost; }
    43                 int get_signCost() const { return signCost; }
    44                 int get_varCost() const { return varCost; }
    45                 int get_specCost() const { return specCost; }
    46                 int get_referenceCost() const { return referenceCost; }
    47 
    48                 Cost operator+( const Cost &other ) const;
    49                 Cost &operator+=( const Cost &other );
    50                 bool operator<( const Cost &other ) const;
    51                 bool operator==( const Cost &other ) const;
    52                 bool operator!=( const Cost &other ) const;
    53                 friend std::ostream &operator<<( std::ostream &os, const Cost &cost );
    54                 // returns negative for *this < other, 0 for *this == other, positive for *this > other
    55                 int compare( const Cost &other ) const;
    56 
    57                 static const Cost zero;
    58                 static const Cost infinity;
    59 
    60                 static const Cost unsafe;
    61                 static const Cost poly;
    62                 static const Cost safe;
    63                 static const Cost sign;
    64                 static const Cost var;
    65                 static const Cost spec;
    66                 static const Cost reference;
    67 
    68           private:
    69                 int unsafeCost;     ///< Unsafe (narrowing) conversions
    70                 int polyCost;       ///< Count of parameters and return values bound to some poly type
    71                 int safeCost;       ///< Safe (widening) conversions
    72                 int signCost;       ///< Count of safe sign conversions
    73                 int varCost;        ///< Count of polymorphic type variables
    74                 int specCost;       ///< Polymorphic type specializations (type assertions), negative cost
    75                 int referenceCost;  ///< reference conversions
    76         };
    77 
    78         inline Cost::Cost( int unsafeCost, int polyCost, int safeCost, int signCost,
    79                                            int varCost, int specCost, int referenceCost )
    80                 : unsafeCost( unsafeCost ), polyCost( polyCost ), safeCost( safeCost ), signCost( signCost ),
    81                   varCost( varCost ), specCost( specCost ), referenceCost( referenceCost ) {}
    82 
    83         inline Cost & Cost::incUnsafe( int inc ) {
    84                 if ( *this == infinity ) return *this;
    85                 unsafeCost += inc;
    86                 return *this;
    87         }
    88 
    89         inline Cost & Cost::incPoly( int inc ) {
    90                 if ( *this == infinity ) return *this;
    91                 polyCost += inc;
    92                 return *this;
    93         }
    94 
    95         inline Cost & Cost::incSafe( int inc ) {
    96                 if ( *this == infinity ) return *this;
    97                 safeCost += inc;
    98                 return *this;
    99         }
    100 
    101         inline Cost & Cost::incSign( int inc ) {
    102                 if ( *this == infinity ) return *this;
    103                 signCost += inc;
    104                 return *this;
    105         }
    106 
    107         inline Cost & Cost::incVar( int inc ) {
    108                 if ( *this == infinity ) return *this;
    109                 varCost += inc;
    110                 return *this;
    111         }
    112 
    113         inline Cost& Cost::decSpec( int dec ) {
    114                 if ( *this == infinity ) return *this;
    115                 specCost -= dec;
    116                 return *this;
    117         }
    118 
    119         inline Cost & Cost::incReference( int inc ) {
    120                 if ( *this == infinity ) return *this;
    121                 referenceCost += inc;
    122                 return *this;
    123         }
    124 
    125         inline Cost Cost::operator+( const Cost &other ) const {
    126                 if ( *this == infinity || other == infinity ) return infinity;
    127                 return Cost{
    128                         unsafeCost + other.unsafeCost, polyCost + other.polyCost, safeCost + other.safeCost,
    129                                 signCost + other.signCost, varCost + other.varCost, specCost + other.specCost,
    130                                 referenceCost + other.referenceCost };
    131         }
    132 
    133         inline Cost &Cost::operator+=( const Cost &other ) {
    134                 if ( *this == infinity ) return *this;
    135                 if ( other == infinity ) {
    136                         *this = infinity;
    137                         return *this;
    138                 }
    139                 unsafeCost += other.unsafeCost;
    140                 polyCost += other.polyCost;
    141                 safeCost += other.safeCost;
    142                 signCost += other.signCost;
    143                 varCost += other.varCost;
    144                 specCost += other.specCost;
    145                 referenceCost += other.referenceCost;
    146                 return *this;
    147         }
    148 
    149         inline bool Cost::operator<( const Cost &other ) const {
    150                 if ( *this == infinity ) return false;
    151                 if ( other == infinity ) return true;
    152 
    153                 if ( unsafeCost > other.unsafeCost ) {
    154                         return false;
    155                 } else if ( unsafeCost < other.unsafeCost ) {
    156                         return true;
    157                 } else if ( polyCost > other.polyCost ) {
    158                         return false;
    159                 } else if ( polyCost < other.polyCost ) {
    160                         return true;
    161                 } else if ( safeCost > other.safeCost ) {
    162                         return false;
    163                 } else if ( safeCost < other.safeCost ) {
    164                         return true;
    165                 } else if ( signCost > other.signCost ) {
    166                         return false;
    167                 } else if ( signCost < other.signCost ) {
    168                         return true;
    169                 } else if ( varCost > other.varCost ) {
    170                         return false;
    171                 } else if ( varCost < other.varCost ) {
    172                         return true;
    173                 } else if ( specCost > other.specCost ) {
    174                         return false;
    175                 } else if ( specCost > other.specCost ) {
    176                         return true;
    177                 } else if ( referenceCost > other.referenceCost ) {
    178                         return false;
    179                 } else if ( referenceCost < other.referenceCost ) {
    180                         return true;
    181                 } else {
    182                         return false;
    183                 } // if
    184         }
    185 
    186         inline int Cost::compare( const Cost &other ) const {
    187                 if ( *this == infinity ) return +1;
    188                 if ( other == infinity ) return -1;
    189 
    190                 int c = unsafeCost - other.unsafeCost; if ( c ) return c;
    191                 c = polyCost - other.polyCost; if ( c ) return c;
    192                 c = safeCost - other.safeCost; if ( c ) return c;
    193                 c = signCost - other.signCost; if ( c ) return c;
    194                 c = varCost - other.varCost; if ( c ) return c;
    195                 c = specCost - other.specCost; if ( c ) return c;
    196                 return referenceCost - other.referenceCost;
    197         }
    198 
    199         inline bool Cost::operator==( const Cost &other ) const {
    200                 return unsafeCost == other.unsafeCost
    201                         && polyCost == other.polyCost
    202                         && safeCost == other.safeCost
    203                         && signCost == other.signCost
    204                         && varCost == other.varCost
    205                         && specCost == other.specCost
    206                         && referenceCost == other.referenceCost;
    207         }
    208 
    209         inline bool Cost::operator!=( const Cost &other ) const {
    210                 return !( *this == other );
    211         }
    212 
    213         inline std::ostream &operator<<( std::ostream &os, const Cost &cost ) {
    214                 return os << "( " << cost.unsafeCost << ", " << cost.polyCost << ", "
    215                           << cost.safeCost << ", " << cost.signCost << ", "
    216                                   << cost.varCost << ", " << cost.specCost << ", "
    217                           << cost.referenceCost << " )";
    218         }
    219 
    220 #else
    221 
    222         //*************************** NEW ***************************
    223 
    22423        // To maximize performance and space, the 7 resolution costs are packed into a single 64-bit word. However, the
    22524        // specialization cost is a negative value so a correction is needed is a few places.
     
    371170                                  << ", " << cost.get_referenceCost() << " )";
    372171        }
    373 #endif // 0
    374172} // namespace ResolvExpr
    375173
  • tests/concurrent/examples/boundedBufferTHREAD.cfa

    r18e683b rc1ea11b  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // boundedBufferEXT.c --
     7// boundedBufferTHREAD.c --
    88//
    99// Author           : Peter A. Buhr
    1010// Created On       : Wed Apr 18 22:52:12 2018
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jun 21 08:15:58 2019
    13 // Update Count     : 23
     12// Last Modified On : Fri Jun 21 11:50:12 2019
     13// Update Count     : 24
    1414//
    1515
  • tools/stat.py

    r18e683b rc1ea11b  
    1111                content = f.readlines()
    1212                content = [x.strip() for x in content]
    13                 content = [int(x) for x in content]
    14                 content.remove(max(content))
    15                 content.remove(min(content))
    16                 med = numpy.around( numpy.median(content), decimals=1)
    17                 avg = numpy.around( numpy.mean  (content), decimals=2)
    18                 std = numpy.around( numpy.std   (content), decimals=2)
    19                 print "median {0} avg {1} stddev {2}".format( med, avg, std )
     13                content = [float(x) for x in content]   # expect floating-point strings
     14                content.remove(max(content))            # need at least 4 data values because
     15                content.remove(min(content))            # the max and min values are removed
     16                med = numpy.median(content)
     17                avg = numpy.mean  (content)
     18                std = numpy.std   (content)
     19                print "median {0:.1f} avg {1:.1f} stddev {2:.2f}".format( med, avg, std )
    2020
    2121
Note: See TracChangeset for help on using the changeset viewer.