class L(object):
    def __init__(self, lst):
        self.l = lst

    def __iter__(self):
        print('iter..')
        for l in self.l:
            yield l

    def __str__(self):
        return ' '.join(self.l)


l1 = L(['1', '2', '3'])
l2 = []
ll2+= l1
print(' '.join(l2))


$ ./a.py
iter..
1 2 3



'Language > Python' 카테고리의 다른 글

[Python] binding function parameter default value.  (0) 2015.09.06


At head of script file:

(CODE-1)
trap 'on_error "${FUNCNAME[@]} ${BASH_LINENO[@]} $LINENO"' ERR
trap 'on_exit' EXIT

Someone may wonder why don't write code like below because it is easier to handle arguments.

(CODE-2)
trap 'on_error "$LINENO ${FUNCNAME[@]} ${BASH_LINENO[@]}"' ERR
trap 'on_exit' EXIT

I don't know there is any documented information related with this. But, results of my experiments are saying that (CODE-2) doens't work as expected.
In case of (CODE-2), my test shows that only latest function-stack information is passed to 'on_error' trap function.
I don't have any idea about the reason. More investigation is required for this.
But anyway, (CODE-1) works well.
So, you can use those arguments to print function call stack at bash.
You may need to use 'BASH_SOURCE' array too, if your bash uses other files, too.



And there is one interesting case. See follow code.

<< Test environment >>
bash: GNU bash, version 4.3.46(1)-release (x86_64-pc-linux-gnu)
OS: Linux XXXX 4.4.0-64-generic #85-Ubuntu SMP Mon Feb 20 11:50:30 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

-------------------------- TEST-1 -----------------------------
<< a.sh >>
function on_err() {
    echo "error"
}

function on_exit() {
    echo "exit"
}

trap on_err ERR
trap on_exit EXIT

myval=$(echo u | grep p)  # global variable


$ bash -eE a.sh
error
exit

-------------------------- TEST-2 -----------------------------

<< a.sh >>
function on_err() {
    echo "error"
}

function on_exit() {
    echo "exit"
}

trap on_err ERR
trap on_exit EXIT

function f0() {
    local myval=$(echo u | grep p)  # local variable in function
}

f0

$ bash -eE a.sh
exit

---------------------------------------------------------------

Even if errtrace is enabled(-E option), 'error' is NOT printed at TEST-2.
Then, is this means 'ERR' is NOT trapped at TEST-2? That is, does 'on_err' not executed?
Let's have a look following code.

-------------------------- TEST-3 -----------------------------

<< a.sh >>
function on_err() {
    echo "error"
}

function on_exit() {
    echo "exit"
}

trap on_err ERR
trap on_exit EXIT

function f0() {
    myval=$(echo u | grep p)  # NOT local variable anymore.
}

f0

$ bash -eE a.sh
error
exit

-------------------------- TEST-4 -----------------------------

<< a.sh >>
function on_err() {
    echo "error" 1>&2  # echo to standard error.
}

function on_exit() {
    echo "exit"
}

trap on_err ERR
trap on_exit EXIT

function f0() {
    local myval=$(echo u | grep p)  # local variable
}

f0

$ bash -eE a.sh
error
exit

-------------------------- TEST-5 -----------------------------


function on_err() {
    echo "error" 1>&2  # echo to stderr
}

function on_exit() {
    echo "exit"
}

trap on_err ERR
trap on_exit EXIT

myval=$(echo u | grep p)  # assign to global variable.


$ bash -eE a.sh
error
error
exit


-------------------------- TEST-6 -----------------------------


function on_err() {
    true  # There is no echo
}

function on_exit() {
    echo "exit"
}

trap on_err ERR
trap on_exit EXIT

myval=$(echo u | grep p)  # asign to global variable


$ bash -eE a.sh
exit

---------------------------------------------------------------

It's very interesting, isn't it?
Further investigation will be continued for this issue.



'Language > Bash' 카테고리의 다른 글

[Bash] 'set -e' inheritance...???  (0) 2017.05.19

StackOverlow 의 아래 답변을 참고하자.

http://stackoverflow.com/questions/2213340/what-is-daemon-thread-in-java


정리하면, JVM은 main thread가 끝나더라도, 아직 수행중인 다른 thread - non daemon thread(user thread) - 가 있다면, 중지되지 않는다.

즉, process가 계속해서 돈다.

C/C++ 처럼, main thread가 exit될 때 process를 종료시키려면, 모든 child thread 속성을 daemon thread로 설정해야 한다.


Thread t = new Thread(...)

t.setDaemon(true);


남아 있는 모든 thread가 Daemon thread일 경우, JVM은 중지된다.

다만, 이런식으로 thread가 급작스레 종료하는 것은 상당히 불안정한 결과를 가져 올 수 있으므로 주의해야 한다.


다시 말하면, 단 하나라도 종료되지 않은 user thread (non-daemon thread) 가 존재할 경우, JVM은 종료되지 않고, 모든 다른 thread (Daemon thraed 포함)역시 계속해도 수행된다.



In general, main function is used as below.


int main(int argc, const char *argv[]) {

}


But, it can be expanded like below


int main(int argc, const char *argv[], const char **envp) {

        while (*envp) {

                printf("%s\n", *envp++);

        }

}


By this way, we can use environment variables easily.

=> This matches parameters of execle() and execvpe() at Linux.



'Language > C&C++' 카테고리의 다른 글

[C/C++] __attribute__((constructor)) and variable initialization in C++.  (0) 2024.01.23
[C/C++] Template with value  (0) 2015.04.28
[C/C++] sizeof array  (0) 2015.03.19
[Macro] '##' macro operator  (0) 2015.02.11
'malloc' and 'Segmentation fault'  (0) 2014.07.25

function 을 define하는 시점에 default value를 binding한다.

(Spec.을 찾아본건 아니고.. 시험적으로...)



[test.py]


_DEFVAL = 10


def set_def(val):

    global _DEFVAL

    _DEFVAL = val


def prdef(val=_DEFVAL):

    print '+++ ' + str(val) + '\n'


prdef()

set_def(0)

prdef()


============== outputs ==============

+++ 10


+++ 10


'Language > Python' 카테고리의 다른 글

[Python] __iter__ method of class at add operator with list...  (0) 2017.05.19

#include <stdio.h>


template<int N> class A {

public:

        A() { a = N;}

        int a;

};


int

main() {

        A<10> *a = new A<10>();

        printf("%d\n", a->a);

        return 0;

}


type이 아니라, 변수 값을 전달할 수도 있다. 이 경우 장점은?

compile time에 값이 정해지므로 compiler가 code를 optimize할 수 있다.



예.


[ a. cpp ]

#include <stdio.h>


template<int N> class A {

public:

        A(int n) { mN = n; }

        void speak() {

                if (N > 5)

                        printf("I'm BIG\n");

                else

                        printf("I'm SMALL\n");

        }

        int mN;

};


int

main() {

        A<10> *a = new A<10>(10);

        A<2> *b = new A<2>(2);

        a->speak();

        b->speak();

        return 0;

}


<< objdump >>

...

        void speak() {

   0: 55                   push   %rbp

   1: 48 89 e5             mov    %rsp,%rbp

   4: 48 83 ec 10           sub    $0x10,%rsp

   8: 48 89 7d f8           mov    %rdi,-0x8(%rbp)

                if (N > 5)

                        printf("I'm BIG\n");

   c: bf 00 00 00 00       mov    $0x0,%edi

  11: e8 00 00 00 00       callq  16 <_ZN1AILi10EE5speakEv+0x16>

                else

                        printf("I'm SMALL\n");

        }

  16: c9                   leaveq 

  17: c3                   retq   


...


        void speak() {

   0: 55                   push   %rbp

   1: 48 89 e5             mov    %rsp,%rbp

   4: 48 83 ec 10           sub    $0x10,%rsp

   8: 48 89 7d f8           mov    %rdi,-0x8(%rbp)

                if (N > 5)

                        printf("I'm BIG\n");

                else

                        printf("I'm SMALL\n");

   c: bf 00 00 00 00       mov    $0x0,%edi

  11: e8 00 00 00 00       callq  16 <_ZN1AILi2EE5speakEv+0x16>

        }

  16: c9                   leaveq 

  17: c3                   retq   


...






[ b. cpp ]

#include <stdio.h>


template<int N> class A {

public:

        A(int n) { mN = n; }

        void speak() {

                if (mN > 5)

                        printf("I'm BIG\n");

                else

                        printf("I'm SMALL\n");

        }

        int mN;

};


int

main() {

        A<10> *a = new A<10>(10);

        A<2> *b = new A<2>(2);

        a->speak();

        b->speak();

        return 0;

}



<< objdump >>

...

        void speak() {

   0: 55                   push   %rbp

   1: 48 89 e5             mov    %rsp,%rbp

   4: 48 83 ec 10           sub    $0x10,%rsp

   8: 48 89 7d f8           mov    %rdi,-0x8(%rbp)

                if (mN > 5)

   c: 48 8b 45 f8           mov    -0x8(%rbp),%rax

  10: 8b 00                 mov    (%rax),%eax

  12: 83 f8 05             cmp    $0x5,%eax

  15: 7e 0c                 jle    23 <_ZN1AILi10EE5speakEv+0x23>

                        printf("I'm BIG\n");

  17: bf 00 00 00 00       mov    $0x0,%edi

  1c: e8 00 00 00 00       callq  21 <_ZN1AILi10EE5speakEv+0x21>

  21: eb 0a                 jmp    2d <_ZN1AILi10EE5speakEv+0x2d>

                else

                        printf("I'm SMALL\n");

  23: bf 00 00 00 00       mov    $0x0,%edi

  28: e8 00 00 00 00       callq  2d <_ZN1AILi10EE5speakEv+0x2d>

        }

  2d: c9                   leaveq 

  2e: c3                   retq   


...


        void speak() {

   0: 55                   push   %rbp

   1: 48 89 e5             mov    %rsp,%rbp

   4: 48 83 ec 10           sub    $0x10,%rsp

   8: 48 89 7d f8           mov    %rdi,-0x8(%rbp)

                if (mN > 5)

   c: 48 8b 45 f8           mov    -0x8(%rbp),%rax

  10: 8b 00                 mov    (%rax),%eax

  12: 83 f8 05             cmp    $0x5,%eax

  15: 7e 0c                 jle    23 <_ZN1AILi2EE5speakEv+0x23>

                        printf("I'm BIG\n");

  17: bf 00 00 00 00       mov    $0x0,%edi

  1c: e8 00 00 00 00       callq  21 <_ZN1AILi2EE5speakEv+0x21>

  21: eb 0a                 jmp    2d <_ZN1AILi2EE5speakEv+0x2d>

                else

                        printf("I'm SMALL\n");

  23: bf 00 00 00 00       mov    $0x0,%edi

  28: e8 00 00 00 00       callq  2d <_ZN1AILi2EE5speakEv+0x2d>

        }

  2d: c9                   leaveq 

  2e: c3                   retq   

...




===============================================


위의 코드를 보면, template 의 value를 사용할 경우, 'if'문에서, 사용되지 않는 코드가 compile시 object에 반영되지 않고 삭제되어 버리는 것을 알 수 있다.

즉 compile time에 충분히 optimize되어 버린다. (if 문의 condition이 compile time에 결정될 수 있으므로...)

[[ Tested on GCC 4.x ]]


static void

test01_00(char buf[TEST01_SZ]) {

        printf("In func: %lu\n", sizeof(buf));

}


static void

test01(void) {

        char buf[TEST01_SZ];

        printf("In local: %lu\n", sizeof(buf));

        test01_00(buf);

}


int

main(int argc, const char *argv[]) {

        test01();

        return 0;

}


<< Run on 64bit linux >>

$ ./a.out

In local: 16   <== array size

In func: 8     <== pointer size


'sizeof(<array>)' works as expected in the scope where it is declared. But, array that is declared as parameter, is regarded same as 'pointer' (as you can see above).

I don't think this is defined in C specification.

So, I think it is just one of special characteristics of GCC.

Is it interesting,isn't it?


즉 array를 선언한 곳에서 sizeof(<array>)는 기대한 대로 동작하는데, argument로 넘긴 array의 경우, pointer와 동일하게 취급하는 것을 알 수 있다.

개인적인 생각으로, 이것이, C spec 사항일 것 같지는 않다.

그러니, 그냥 GCC 특성 중 하나라고 생각한다....

꽤나 재미있는 내용이라, 일단 적어 둔다. ^_^

'Language > C&C++' 카테고리의 다른 글

[C/C++] Small tip - Argument passed to main() function.  (0) 2015.10.19
[C/C++] Template with value  (0) 2015.04.28
[Macro] '##' macro operator  (0) 2015.02.11
'malloc' and 'Segmentation fault'  (0) 2014.07.25
[GCC] Initialize array...  (0) 2014.07.25

* '##' macro operator (improved)


<token> ## <token>

: The ## operator takes two separate tokens and paste them together to form a single token.


즉:


#define test(x) aa ## _x

#define test(x) aa##_x


위의 두가지 모두 결과는 'aa_x' 로 같다.

('##' 사용시 중간에 공백은 token delimiter 의 역할을 하게 된다.)

'Language > C&C++' 카테고리의 다른 글

[C/C++] Template with value  (0) 2015.04.28
[C/C++] sizeof array  (0) 2015.03.19
'malloc' and 'Segmentation fault'  (0) 2014.07.25
[GCC] Initialize array...  (0) 2014.07.25
[Linux] Using named pipe in linux (주의할 점)  (0) 2014.01.09

'Segmentation fault' is very familiar error for C developer.

Then, when this runtime error is issued?

At the moment of accessing not-allocated-memory?

This may be right, but this is NOT strict enough.

'Segmentation fault' is issued by kernel through signal to notify that,

"You - user process - try to access not-permitted memory area. And usually, this happens when it tries to access not-allocated-memory - for the user process (In case of ARM architecture, it is triggered by Data Abort cpu exception).


Let's see below code.

#include <stdio.h>
#include <stdlib.h>

int
main(int argc, const char *argv[]) {
        int i = 0;
        char *s = malloc(1);
        s += 1;
        for (i = 0; i < 1024 * 1024 * 1024; i++) {
                printf("%d\n", i);
                s[i] = 4;
        }
        return 0;
}

Do you think when this process is stopped by 'Segmentation fault' signal?

"i == 0" ? (that is at the first moment of trying to access not-allocated-memory-by-malloc).


It, is totally up to malloc implementation.

But, at above case, this is definitely NO.

The reason is, kernel(linux) allocate memory for user process at least 1-page.

So, above code will run even if i > 1024 especially on the Linux machine.


And, there are various implementation(algorithm) of malloc.

So, we cannot expect exact value of i for above code.

Important thing to know here is, answer the question - "What exactly does 'Segmentation fault' mean?"


'Language > C&C++' 카테고리의 다른 글

[C/C++] sizeof array  (0) 2015.03.19
[Macro] '##' macro operator  (0) 2015.02.11
[GCC] Initialize array...  (0) 2014.07.25
[Linux] Using named pipe in linux (주의할 점)  (0) 2014.01.09
[c/c++] file copy using 'sendfile' on linux.  (0) 2013.12.17

See https://gcc.gnu.org/onlinedocs/gcc-4.4.4/gcc/Designated-Inits.html


And here is one more tips.

Sometimes, you may want to initialize all array element with same value.

Then, you can do it as follows if you are using GCC.


static const int arr[10] = {[0 ... (sizeof(arr)/sizeof(arr[0]) - 1)] = 10};



+ Recent posts