LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   SEGMENTATION FAULT using gcc 4.4.4 -O2 , works with gcc 4.1.0 -O2 or gcc 4.4.4 -O1 (https://www.linuxquestions.org/questions/programming-9/segmentation-fault-using-gcc-4-4-4-o2-works-with-gcc-4-1-0-o2-or-gcc-4-4-4-o1-822124/)

amir1981 07-26-2010 04:28 PM

Quote:

Originally Posted by johnsfine (Post 4046175)
If you just need portability across modern 32 bit and 64 bit architectures, you can just drop the l from your 32 bit format strings: Use %u instead of %lu and use %d for signed 32 bit.

Thanks a lot.It was the problem, as a work around I have used long variable to read from sscanf now, but I'm looking for a more decent solution that works in for example in 128 bit systems too.
Do you think if I remove all 'l''s from formatting strings can I be hopeful that this code would not break again for this reason?

Sergei Steshenko 07-26-2010 04:51 PM

Quote:

Originally Posted by amir1981 (Post 4046196)
Thanks a lot.It was the problem, as a work around I have used long variable to read from sscanf now, but I'm looking for a more decent solution that works in for example in 128 bit systems too.
Do you if I remove all 'l''s from formatting strings can I be hopeful that this code would not break again for this reason?

I would go the other way round in order to make my code portable. I.e. I am using the following idiom:

Code:

printf("some_int_var=%ll\n", (long long)some_int_var);
- this works regardless of 32/64 bits and regardless of actual integer type of some_int_var - by construction.

amir1981 07-26-2010 04:59 PM

Quote:

Originally Posted by Sergei Steshenko (Post 4046210)
I would go the other way round in order to make my code portable. I.e. I am using the following idiom:

Code:

printf("some_int_var=%ll\n", (long long)some_int_var);
- this works regardless of 32/64 bits and regardless of actual integer type of some_int_var - by construction.

thanks but I think here the situation is a bit different for example look at this:
bool8 SysString::get(int16& val_a) const {

// declare local variable
//
int32 tmp_val = 0;

// use the 8-bit character conversion
//
if (sscanf((char*)(byte8*)(*this),
(char*)DEF_FMT_LONG_8BIT, &tmp_val) != 1) {
return false;
}

// set the output
//
val_a = tmp_val;

// exit gracefully
//
return true;
}

Generally I want to specify the type of my variables to use certain number of bits so these variables should be exactly the same on all Machines. For formats we have:
const char SysString::DEF_FMT_LONG_8BIT[] = "%ld";

Now if change formats to for example this:
const char SysString::DEF_FMT_LONG_8BIT[] = "%d";

Can I be hopeful to get the same result for example on 128-bit machines too? I mean is it likely that "%d" definition change again?

johnsfine 07-26-2010 05:08 PM

Quote:

Originally Posted by amir1981 (Post 4046214)
thanks but I think here the situation is a bit different

Only because you are enforcing your own rules beyond where they should apply.

In your design, you want val_a to be an explicit size independent of architecture. That makes sense.

But you are being too strict in deciding tmp_val is also an explicit size independent of architecture. tmp_val exists only to interface to sscanf. sscanf does not work with explicit sizes independent of architecture.

So you should change your objective to just make sure tmp_val is at least as big as val_a. There are lots of ways of doing that while declaring tmp_val as some architecture specific size that is compatible with sscanf.

Mainly your problem is wrapped up in your choice of using sscanf at all. This is C++ code. sscanf is a lame holdover from C. If you were using some kind of stringstream as the text side source and using operator>> instead of sscanf then the operator overloading of streams would fit the format to the destination automatically rather than requiring all this work on your part to do so.

I have no idea what a 128 bit architecture would look like. Lots of different things are different sizes in each architecture. But the virtual address size has been the primary driver of the size naming of architectures.

You might think that the exponential growth from 16 bit virtual addresses to 32 bit virtual addresses to 64 bit virtual addresses would logically continue to 128 bit. But it won't:

16 bit virtual addresses were already too small when 16 bit x86 was introduced and were horribly too small by the time 32 bit x86 was introduced.

32 bit virtual addresses were plenty large enough when introduced and were still mostly large enough when 64 bit was introduced.

32 bits were closer to adequate when 64 bits were introduced than 16 bit was when 16 bit x86 itself was introduced. In that sense the available addressing doubled twice while the required addressing only really doubled once.

Then the exponential growth in problem size just needs an exponential growth in memory, which is only a linear growth address size. So the jump from 32 to 64 was is another way twice the jump from 16 to 32. So 64 bit addressing should be plenty for at least four times longer than 32 bit addressing was plenty.

So I think you're trying too hard to guess distant future portability issues.

amir1981 07-26-2010 05:21 PM

Quote:

Originally Posted by johnsfine (Post 4046223)
Only because you are enforcing your own rules beyond where they should apply.

In your design, you want val_a to be an explicit size independent of architecture. That makes sense.

But you are being too strict in deciding tmp_val is also an explicit size independent of architecture. tmp_val exists only to interface to sscanf. sscanf does not work with explicit sizes independent of architecture.

So you should change your objective to just make sure tmp_val is at least as big as val_a. There are lots of ways of doing that while declaring tmp_val as some architecture specific size that is compatible with sscanf.

Mainly your problem is wrapped up in your choice of using sscanf at all. This is C++ code. sscanf is a lame holdover from C. If you were using some kind of stringstream as the text side source and using operator>> instead of sscanf then the operator overloading of streams would fit the format to the destination automatically rather than requiring all this work on your part to do so.

You're right but this code is not written by me, and I am just trying to update it. Maybe I can change sscanf too, I think it makes sense.
Anyway, thanks a lot. All of you ,specially john, were very helpful.

Sergei Steshenko 07-26-2010 05:31 PM

Quote:

Originally Posted by amir1981 (Post 4046214)
thanks but I think here the situation is a bit different for example look at this:
bool8 SysString::get(int16& val_a) const {

// declare local variable
//
int32 tmp_val = 0;

// use the 8-bit character conversion
//
if (sscanf((char*)(byte8*)(*this),
(char*)DEF_FMT_LONG_8BIT, &tmp_val) != 1) {
return false;
}

// set the output
//
val_a = tmp_val;

// exit gracefully
//
return true;
}

Generally I want to specify the type of my variables to use certain number of bits so these variables should be exactly the same on all Machines. For formats we have:
const char SysString::DEF_FMT_LONG_8BIT[] = "%ld";

Now if change formats to for example this:
const char SysString::DEF_FMT_LONG_8BIT[] = "%d";

Can I be hopeful to get the same result for example on 128-bit machines too? I mean is it likely that "%d" definition change again?

First of all, I agree with http://www.linuxquestions.org/questi...ml#post4046223 .

Secondly, you need fixed sizes only if/when you deal with HW generated data, e.g. if/when you deal with, say, Ethernet packet. I don't see a case when one needs "bool8" (taken from http://www.linuxquestions.org/questi...ml#post4046144 ).

I.e. I would give the compiler to choose width of 'bool' type.

Anyway, if you want to complicate things, you still can use constructs like


Code:

if(sizeof(my_int_var) == sizeof(int))
  {
  printf("my_int_var=%d\n", my_int_var);
  }

if(sizeof(my_int_var) == sizeof(long))
  {
  printf("my_int_var=%l\n", my_int_var);
  }

- in such cases 'sizeof' is known at compile time, so all the unnecessary 'if's will be optimized out at compile time.

This can be scripted (i.e. C++ code can be generated by a script) and can probably be implemented through templates.

Still, rethink the whole issue of imposed size variables.

acvoight 07-26-2010 06:07 PM

Edit - Misread (can't delete?)


All times are GMT -5. The time now is 04:30 PM.