Re: (main_buf = *main_buf_p) is not syntacticly like (i = *j) ?
On Tue, Jul 03, 2001 at 12:13:47AM +0300, Shaul Karl wrote: Thank you for the responses. What I have done wrong is already pointed out. If you are curious what I am trying to do: 1. I wanted to have jmp_buf* passed as a function parameter in order to avoid a global variable. Therefore, in the function body I had to use a local variable and initialize it with this pointer: jmp_buf local_variable = *function_paramter; You're using jmp_buf as an exception throwing mechanism. I'd say it WOULD make sense to have jmp_buf a global (or per-thread, yuck) variable, since exceptions are global by nature. It would be also more portable, unless the standard mandates that jmp_buf is an array -- anyone happens to know if it does? = To unsubscribe, send mail to [EMAIL PROTECTED] with the word unsubscribe in the message body, e.g., run the command echo unsubscribe | mail [EMAIL PROTECTED]
Re: (main_buf = *main_buf_p) is not syntacticly like (i = *j) ?
Nadav Har'El wrote: On Tue, Jul 03, 2001, Shaul Karl wrote about Re: (main_buf = *main_buf_p) is not syntacticly like (i = *j) ?: Thank you for the responses. You're welcome. I bet you didn't expect so many correct responses. Well, I take the credit for the first response (my response is dated a whole 55 seconds before Shachar's ;) ) Ok, I get the picture. Two conclusions I can draw from this thread: A. Never sound as if you think a fellow poster doesn't know what he's talking about, esp. not one you know and respect. B. Never stop to check (or, alternatively, set your clock back a minute or two). C. Don't bother with other platforms on a linux only mailing list, even if they are readily available to you. D. Always count the number of points you are going to give AFTER you finish writing them. 1. I wanted to have jmp_buf* passed as a function parameter in order to avoid a global variable. Therefore, in the function body I had to use a local variable and initialize it with this pointer: jmp_buf local_variable = *function_paramter; Why pass a jmp_buf* when you can pass the jmp_buf itself? Since in C arrays are in any case passed as pointers, you don't need the extra layer of indirection. If you're worried that jmp_buf might be some sort of compound type that can't be passed as a parameter, worry no more: remember, setjmp() and longjmp() are functions too, and if they can take a jmp_buf, so can you. (anyway, ANSI C no longer has any problems with passing structures as parameters, so you can pass any type (except void?) as a parameter). jmp_buf is potentially a big variable. After all, it should contain your entire environment. It is also a typedef, so you don't want to trust the fact that it is currently an array (as Nadav pointed out, it is extremely easy to take pointers to arrays without noticing, the reason many people don't distinguish the two). Since that's the case, I would recommend taking the pointer and then derefrencing. I would still go for for Nadav remark two paragraphs down. So I suggest you just give the function a jmp_buf parameter, exactly like setjmp/longjmp have, and forget about this useless copying. BTW, even if you insist on passing a jmp_buf*, you don't need to copy it to do dereference the pointer. You do something like longjmp(*function_parameter); (unless there's another pointer vs. array problem I'm not thinking of right now - I'm too tired to think clearly right now ;)) don't think there is, but havn't stopped to ponder it deeply. 2. The work I am doing is just my homework in a compilation course. .. suppose you have an interactive program that has a main loop that prompts for and executes commands. Suppose the read command reads input from a file, doing some lexical analysis and parsing of the input while processing it. If a low-level input error is detected, it would be useful to be able to return immediately to the main loop instead of having to make each of the lexical analysis, parsing, and processing phases all have to explicitly deal with error situations initially detected by nested calls. Interesting coincidence: the only time I *ever* used longjmp was in an interpreter I wrote, and I used it in the error handler, which had to reset the interpreter's state and continue processing the next statement. Yet another coincidence. I used the longs jumps functions extensively, though through a slightly different interface. The most notable case was a parser too. For those of you wondering - the different interface was in C++, and the function name (operator, actually) was throw. = To unsubscribe, send mail to [EMAIL PROTECTED] with the word unsubscribe in the message body, e.g., run the command echo unsubscribe | mail [EMAIL PROTECTED]
Re: (main_buf = *main_buf_p) is not syntacticly like (i = *j) ?
Adi Stav wrote: On Tue, Jul 03, 2001 at 12:13:47AM +0300, Shaul Karl wrote: Thank you for the responses. What I have done wrong is already pointed out. If you are curious what I am trying to do: 1. I wanted to have jmp_buf* passed as a function parameter in order to avoid a global variable. Therefore, in the function body I had to use a local variable and initialize it with this pointer: jmp_buf local_variable = *function_paramter; You're using jmp_buf as an exception throwing mechanism. I'd say it WOULD make sense to have jmp_buf a global (or per-thread, yuck) variable, since exceptions are global by nature. Are they short C++ code: void A() { try { class someclass var1(constructor_arguments); B(); some_more_activities(); } catch( ... ) { some_exception_code(); } } void B() { class someotherclass var2( constructor_arguments ); ... C(); } void C() { blah(); if( adi_stav_was_here==true ) throw NOOO(5); } If we try to (as CFront used to do) compile this code into C, we see that the long jump triggered by the throw in function C must stop inside function B, in order to run the var2 destructor. This catch handler can then long jump to function A to handle the explicit catch handler. Conclusion 1 - if you enable exception handling in C++, all your functions probably carry exception handlers (there are good things to say for Java's you must declare exceptions syntax). Conclusion 2 - exceptions are not global, far from it. For those of you still only programming in C, replace destructor with cleanup code. Shachar P.S. I am not trying to say there is anything against Adi Stav being here. I have nothing against Adi Stav in particular, and bearded people in general. Some of my best friends are Adi Stav. = To unsubscribe, send mail to [EMAIL PROTECTED] with the word unsubscribe in the message body, e.g., run the command echo unsubscribe | mail [EMAIL PROTECTED]
Re: (main_buf = *main_buf_p) is not syntacticly like (i = *j) ?
On Tue, Jul 03, 2001 at 03:10:05PM +0200, Shachar Shemesh wrote: short C++ code: void A() { try { class someclass var1(constructor_arguments); B(); some_more_activities(); } catch( ... ) { some_exception_code(); } } void B() { class someotherclass var2( constructor_arguments ); ... C(); } void C() { blah(); if( adi_stav_was_here==true ) throw NOOO(5); } If we try to (as CFront used to do) compile this code into C, we see that the long jump triggered by the throw in function C must stop inside function B, in order to run the var2 destructor. This catch handler can then long jump to function A to handle the explicit catch handler. I've never used CFront. But why would an implicit exception handler be different from an explicit one? That could easily be implemented by having each exception handler keep a pointer to the previous jmp_buf, restore it once it finishes (either naturally or through exception). Conclusion 1 - if you enable exception handling in C++, all your functions probably carry exception handlers (there are good things to say for Java's you must declare exceptions syntax). If it makes you happy, I've always considered those kind of safe destructors the most useful thing in C++, and the lack of useable exceptions the most annoying feature-lack of C. Conclusion 2 - exceptions are not global, far from it. You always have only one active exception handler at a time. That's what I mean by global. Can you imagine a situation where you'd want to pass one of two jmp_buf pointers, say, based on the value of a flag? For those of you still only programming in C, replace destructor with cleanup code. Actually I find that a lot of people nowdays start with C++ or Java and move to C later. Like I did, even though I switched very early experience-wise. = To unsubscribe, send mail to [EMAIL PROTECTED] with the word unsubscribe in the message body, e.g., run the command echo unsubscribe | mail [EMAIL PROTECTED]
Re: (main_buf = *main_buf_p) is not syntacticly like (i = *j) ?
Isn't is amazing that the same people that jump to your throat when they think that something off-topic is posted, are the same people who will galdly join an off-topic religious war on the list ? Please, stop this Thread, --ury = To unsubscribe, send mail to [EMAIL PROTECTED] with the word unsubscribe in the message body, e.g., run the command echo unsubscribe | mail [EMAIL PROTECTED]
(main_buf = *main_buf_p) is not syntacticly like (i = *j) ?
I have two 11 lines C programs which are supposed to be syntacticly similar. Yet int_test.c get compiled while the other does not: Script started on Mon Jul 2 14:51:10 2001 [14:51:10 tmp]$ more *_test.c :: int_test.c :: #include setjmp.h int main() { int i; int *j = i; i = *j; return 0; } :: jmp_test.c :: #include setjmp.h int main() { jmp_buf test_env; jmp_buf *test_env_p = test_env; test_env = *test_env_p; return 0; } [14:51:25 tmp]$ cc -Wall -c int_test.c [14:51:47 tmp]$ cc -Wall -c jmp_test.c jmp_test.c: In function `main': jmp_test.c:9: incompatible types in assignment [14:51:56 tmp]$ exit exit Script done on Mon Jul 2 14:52:02 2001 What did I miss? -- Shaul Karl [EMAIL PROTECTED] Hillel used to say: If I am not for myself who will be for me? Yet, if I am for myself only, what am I? And if not now, when? (Ethics Of The Fathers 1:14) = To unsubscribe, send mail to [EMAIL PROTECTED] with the word unsubscribe in the message body, e.g., run the command echo unsubscribe | mail [EMAIL PROTECTED]
Re: (main_buf = *main_buf_p) is not syntacticly like (i = *j) ?
On Mon, Jul 02, 2001, Shaul Karl wrote about (main_buf = *main_buf_p) is not syntacticly like (i = *j) ?: #include setjmp.h int main() { jmp_buf test_env; jmp_buf *test_env_p = test_env; test_env = *test_env_p; return 0; } jmp_test.c:9: incompatible types in assignment What did I miss? Well, the problem is the definition of jmp_buf: in Linux, typedef struct ... jmp_buf[1]; Which means the jmp_buf type is an array. In C you can't normally assign arrays like you did (because C thinks you're trying to assign pointers, rather than the content of the array), so either do *test_env=**test_env_p; (to assign the first element, but this is highly dependent on the linux implementation), or the more portable (and thus better) approach is to use memcpy() to copy a jmp_buf. BTW, don't forget the following NOTES from the Linux setjmp() manual: setjmp() and sigsetjmp make programs hard to understand and maintain. If possible an alternative should be used. -- Nadav Har'El| Monday, Jul 2 2001, 11 Tammuz 5761 [EMAIL PROTECTED] |- Phone: +972-53-245868, ICQ 13349191 |Experience is what causes a person to http://nadav.harel.org.il |make new mistakes instead of old ones. = To unsubscribe, send mail to [EMAIL PROTECTED] with the word unsubscribe in the message body, e.g., run the command echo unsubscribe | mail [EMAIL PROTECTED]
Re: (main_buf = *main_buf_p) is not syntacticly like (i = *j) ?
Tthe type jmp_buf is a typedef of an ARRAY. As such, an array cannot be directly assigned to, only its elements. This code produces the same error as the second program: (Note the substitution of 'int' for 'int[1]' via typedef) typedef int foo[1]; int main() { foo i; foo *j = i; i = *j; return 0; } Hope this helps, -Eyal At 02:00 PM 7/2/2001, Shaul Karl wrote: I have two 11 lines C programs which are supposed to be syntacticly similar. Yet int_test.c get compiled while the other does not: Script started on Mon Jul 2 14:51:10 2001 [14:51:10 tmp]$ more *_test.c :: int_test.c :: #include setjmp.h int main() { int i; int *j = i; i = *j; return 0; } :: jmp_test.c :: #include setjmp.h int main() { jmp_buf test_env; jmp_buf *test_env_p = test_env; test_env = *test_env_p; return 0; } [14:51:25 tmp]$ cc -Wall -c int_test.c [14:51:47 tmp]$ cc -Wall -c jmp_test.c jmp_test.c: In function `main': jmp_test.c:9: incompatible types in assignment [14:51:56 tmp]$ exit exit Script done on Mon Jul 2 14:52:02 2001 What did I miss? -- Shaul Karl [EMAIL PROTECTED] Hillel used to say: If I am not for myself who will be for me? Yet, if I am for myself only, what am I? And if not now, when? (Ethics Of The Fathers 1:14) = To unsubscribe, send mail to [EMAIL PROTECTED] with the word unsubscribe in the message body, e.g., run the command echo unsubscribe | mail [EMAIL PROTECTED] = To unsubscribe, send mail to [EMAIL PROTECTED] with the word unsubscribe in the message body, e.g., run the command echo unsubscribe | mail [EMAIL PROTECTED]
Re: (main_buf = *main_buf_p) is not syntacticly like (i = *j) ?
Nadav Har'El wrote: Which means the jmp_buf type is an array. In C you can't normally assign arrays like you did (because C thinks you're trying to assign pointers, rather than the content of the array), so either do Slight correction. I know I lost a bet over this, and I know many people make this mistake. The compiler doesn't view arrays as pointers. Arrays and pointers are distinct things in C. They are easily castable one into the other, hence the common misconception, but they are defenitely distinct. This is the reason that 2d arrays take n*m*sizeof(type), and not n*m*sizeof(type)+n*sizeof(type *). Sh. = To unsubscribe, send mail to [EMAIL PROTECTED] with the word unsubscribe in the message body, e.g., run the command echo unsubscribe | mail [EMAIL PROTECTED]
Re: (main_buf = *main_buf_p) is not syntacticly like (i = *j) ?
Shaul Karl wrote (and you can't deny): [snip code] What did I miss? The topic. Try comp.lang.c = To unsubscribe, send mail to [EMAIL PROTECTED] with the word unsubscribe in the message body, e.g., run the command echo unsubscribe | mail [EMAIL PROTECTED]
Re: (main_buf = *main_buf_p) is not syntacticly like (i = *j) ?
On Mon, Jul 02, 2001, Shachar Shemesh wrote about Re: (main_buf = *main_buf_p) is not syntacticly like (i = *j) ?: Nadav Har'El wrote: Which means the jmp_buf type is an array. In C you can't normally assign arrays like you did (because C thinks you're trying to assign pointers, rather than the content of the array), so either do Slight correction. I know I lost a bet over this, and I know many people make this mistake. The compiler doesn't view arrays as pointers. Arrays and pointers are distinct things in C. They are easily castable one into the other, hence the common misconception, but they are defenitely distinct. I know very well the difference between arrays and pointers in C, and I don't think I said anything wrong. Take a look at Dennis Ritchie's The Development of the C Language for how the confusion of pointers and arrays came about, and why it's a feature, not a bug :) It's in http://cm.bell-labs.com/cm/cs/who/dmr/chist.html or http://cm.bell-labs.com/cm/cs/who/dmr/chist.pdf. Anyway, I wasn't saying that these were pointers. In fact, if they were, they were assignable, and the whole thing would work. But I meant was: When C sees an array on the right hand of an assignment, it treats it as a pointer, which is why you can do something like char *p, s[7]; p=s; But when it sees an array on the left hand side of the assignment (like the original poster used), it barfs. It should complain that the left-hand side of the assignment is not assignable (in compiler-speak, not an lvalue), and indeed Solaris's compiler says: z.c, line 8: left operand must be modifiable lvalue: op = But gcc's compiler prints the much less clear incompatible types in assignment. It might be because it first converts the right-hand-side to a pointer, but of course cannot do the same for the left-hand-side of the assignment, and then sees it cannot assign a pointer to an array. -- Nadav Har'El| Monday, Jul 2 2001, 11 Tammuz 5761 [EMAIL PROTECTED] |- Phone: +972-53-245868, ICQ 13349191 |Hospitality: Making your guests feel at http://nadav.harel.org.il |home, even if you wish they were. = To unsubscribe, send mail to [EMAIL PROTECTED] with the word unsubscribe in the message body, e.g., run the command echo unsubscribe | mail [EMAIL PROTECTED]
Re: (main_buf = *main_buf_p) is not syntacticly like (i = *j) ?
On Mon, Jul 02, 2001 at 03:00:21PM +0300, Shaul Karl wrote: I have two 11 lines C programs which are supposed to be syntacticly similar. Yet int_test.c get compiled while the other does not: Script started on Mon Jul 2 14:51:10 2001 [14:51:10 tmp]$ more *_test.c :: int_test.c :: #include setjmp.h int main() { int i; int *j = i; i = *j; return 0; } :: jmp_test.c :: #include setjmp.h int main() { jmp_buf test_env; jmp_buf *test_env_p = test_env; test_env = *test_env_p; return 0; } [14:51:25 tmp]$ cc -Wall -c int_test.c [14:51:47 tmp]$ cc -Wall -c jmp_test.c jmp_test.c: In function `main': jmp_test.c:9: incompatible types in assignment [14:51:56 tmp]$ exit exit Script done on Mon Jul 2 14:52:02 2001 What did I miss? I don't think you are supposed to assign jmp_buf, only to use it with setjmp() and longjmp(). It is not a basic compiler type -- it is a system type defined by your libc and/or your OS and there are no guarantees about its definition IIRC. Specifically glibc defines jmpbuf as a 1-size array of a struct (so that calls to functions will only pass a pointer, I suppose), and the incompatible type error is what gcc gives you when you try to assign to an array. If you really want to assign to an array or to any other type, you can always wrap them with a struct, or simply memcpy(). But if you are trying to do that you are probably doing something wrong. What are you after? = To unsubscribe, send mail to [EMAIL PROTECTED] with the word unsubscribe in the message body, e.g., run the command echo unsubscribe | mail [EMAIL PROTECTED]
Re: (main_buf = *main_buf_p) is not syntacticly like (i = *j) ?
Shaul Karl [EMAIL PROTECTED] writes: #include setjmp.h int main() { jmp_buf test_env; jmp_buf *test_env_p = test_env; test_env = *test_env_p; return 0; } I suspect that line 9 is the assignment before the return statement. The assignment can be, and probably is, illegal: jmp_buf is not a scalar type, but an array, and you cannot assign arrays. -- Oleg Goldshmidt | [EMAIL PROTECTED] If it ain't broken, it hasn't got enough features yet. = To unsubscribe, send mail to [EMAIL PROTECTED] with the word unsubscribe in the message body, e.g., run the command echo unsubscribe | mail [EMAIL PROTECTED]
Re: (main_buf = *main_buf_p) is not syntacticly like (i = *j) ?
On Mon, Jul 02, 2001 at 03:32:24PM +0300, Nadav Har'El wrote: On Mon, Jul 02, 2001, Shaul Karl wrote about (main_buf = *main_buf_p) is not syntacticly like (i = *j) ?: #include setjmp.h int main() { jmp_buf test_env; jmp_buf *test_env_p = test_env; test_env = *test_env_p; return 0; } jmp_test.c:9: incompatible types in assignment What did I miss? Well, the problem is the definition of jmp_buf: in Linux, typedef struct ... jmp_buf[1]; Which means the jmp_buf type is an array. In C you can't normally assign arrays like you did (because C thinks you're trying to assign pointers, rather than the content of the array), so either do *test_env=**test_env_p; (to assign the first element, but this is highly dependent on the linux implementation), or the more portable (and thus better) approach is to use memcpy() to copy a jmp_buf. BTW, don't forget the following NOTES from the Linux setjmp() manual: setjmp() and sigsetjmp make programs hard to understand and maintain. If possible an alternative should be used. BTW: if we're already talking about setjmp(), longjmp() and difficulty to understand, has anyone read the article from the GNU Pth source distribution? It deals with applications of setjmp() and similar calls in thread implementations, and I found it fascinatingly mindboggling. = To unsubscribe, send mail to [EMAIL PROTECTED] with the word unsubscribe in the message body, e.g., run the command echo unsubscribe | mail [EMAIL PROTECTED]
Re: (main_buf = *main_buf_p) is not syntacticly like (i = *j) ?
On Tue, Jul 03, 2001, Shaul Karl wrote about Re: (main_buf = *main_buf_p) is not syntacticly like (i = *j) ?: Thank you for the responses. You're welcome. I bet you didn't expect so many correct responses. Well, I take the credit for the first response (my response is dated a whole 55 seconds before Shachar's ;) ) 1. I wanted to have jmp_buf* passed as a function parameter in order to avoid a global variable. Therefore, in the function body I had to use a local variable and initialize it with this pointer: jmp_buf local_variable = *function_paramter; Why pass a jmp_buf* when you can pass the jmp_buf itself? Since in C arrays are in any case passed as pointers, you don't need the extra layer of indirection. If you're worried that jmp_buf might be some sort of compound type that can't be passed as a parameter, worry no more: remember, setjmp() and longjmp() are functions too, and if they can take a jmp_buf, so can you. (anyway, ANSI C no longer has any problems with passing structures as parameters, so you can pass any type (except void?) as a parameter). So I suggest you just give the function a jmp_buf parameter, exactly like setjmp/longjmp have, and forget about this useless copying. BTW, even if you insist on passing a jmp_buf*, you don't need to copy it to do dereference the pointer. You do something like longjmp(*function_parameter); (unless there's another pointer vs. array problem I'm not thinking of right now - I'm too tired to think clearly right now ;)) 2. The work I am doing is just my homework in a compilation course. .. suppose you have an interactive program that has a main loop that prompts for and executes commands. Suppose the read command reads input from a file, doing some lexical analysis and parsing of the input while processing it. If a low-level input error is detected, it would be useful to be able to return immediately to the main loop instead of having to make each of the lexical analysis, parsing, and processing phases all have to explicitly deal with error situations initially detected by nested calls. Interesting coincidence: the only time I *ever* used longjmp was in an interpreter I wrote, and I used it in the error handler, which had to reset the interpreter's state and continue processing the next statement. -- Nadav Har'El| Tuesday, Jul 3 2001, 12 Tammuz 5761 [EMAIL PROTECTED] |- Phone: +972-53-245868, ICQ 13349191 |If glory comes after death, I'm not in a http://nadav.harel.org.il |hurry. (Latin proverb) = To unsubscribe, send mail to [EMAIL PROTECTED] with the word unsubscribe in the message body, e.g., run the command echo unsubscribe | mail [EMAIL PROTECTED]