Pages: [1] 2   Go Down
Author Topic: Trying to combine statements, failing miserably.......  (Read 709 times)
0 Members and 1 Guest are viewing this topic.
Worst state in America
Offline Offline
God Member
*****
Karma: 32
Posts: 792
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi all,

I've been playing with a small function:

Code:
char *buffer_print (char *buf, char *str, uint64_t *siz)
{
        char *ptr; /* pointer to buffer */
        uint64_t len = strlen (str); /* length of incoming string */

        *siz += len; /* update total size */

        ptr = buf = (char *) realloc (buf, *siz * sizeof (char *)); /* new buffer = old buffer + new size */

        ptr += *siz; /* move pointer to end of re-allocated buffer */
        *ptr = 0; /* null terminate last character */
        ptr -= len; /* move pointer to start of newly allocated area */

        while (len--) { /* copy incoming string to new area */
                ptr[len] = str[len];
        }
        return buf; /* return pointer to complete buffer */
}

These three lines of code are driving me nuts:

Code:
        ptr += *siz; /* move pointer to end of re-allocated buffer */
        *ptr = 0; /* null terminate last character */
        ptr -= len; /* move pointer to start of newly allocated area */

I wanted to try to combine them all into one line. I know it's hard to read, bad programming practice, etc...  don't scold me.... I don't intend to do it that way... I'm asking because I TRIED to do it for the heck of it and couldn't get it right!

I figured I would just put it all inside parentheses and it would work... I tried this:

    ((ptr += *siz) = 0) -= len

doesn't work.

Ah-ha! I see my mistake!

    (*(ptr += *siz) = 0) -= len;

Nope....... OH WAIT!!

    &(*(ptr += *siz) = 0) -= len

Still nope..... WHAT THE HECK????????

I must be missing something simple and obvious........ but I'm not seeing it.

Any ideas?

Thanks,

-- Roger
Logged

Gentlemen may prefer Blondes, but Real Men prefer Redheads!

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 126
Posts: 8473
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I suspect people may be more inclined to put some thought into it if there was a point to the exercise smiley, but I'm sure someone will accept the challenge.

______
Rob
Logged

Rob Gray aka the GRAYnomad www.robgray.com

Global Moderator
Dallas
Online Online
Shannon Member
*****
Karma: 200
Posts: 12777
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset


Are commas allowed?
Logged

Johannesburg. UTC+2
Online Online
Faraday Member
**
Karma: 82
Posts: 3858
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hmmm, failing miserably meets coding badly.... that's going to work!  smiley-cool
Logged

The Elders of the Internet know who I am.....

Worst state in America
Offline Offline
God Member
*****
Karma: 32
Posts: 792
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I suspect people may be more inclined to put some thought into it if there was a point to the exercise smiley, but I'm sure someone will accept the challenge.

______
Rob


What's "the point" of climbing a mountain? smiley
Logged

Gentlemen may prefer Blondes, but Real Men prefer Redheads!

Worst state in America
Offline Offline
God Member
*****
Karma: 32
Posts: 792
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset


Are commas allowed?

Are commas necessary? 
Logged

Gentlemen may prefer Blondes, but Real Men prefer Redheads!

Worst state in America
Offline Offline
God Member
*****
Karma: 32
Posts: 792
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hmmm, failing miserably meets coding badly.... that's going to work!  smiley-cool
HA! I laughed out loud. Literally.  smiley
Logged

Gentlemen may prefer Blondes, but Real Men prefer Redheads!

Johannesburg. UTC+2
Online Online
Faraday Member
**
Karma: 82
Posts: 3858
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hmmm, failing miserably meets coding badly.... that's going to work!  smiley-cool
HA! I laughed out loud. Literally.  smiley

Well I'm glad I managed to brighten someone's day so far....
Logged

The Elders of the Internet know who I am.....

Offline Offline
God Member
*****
Karma: 17
Posts: 522
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I can do it in one line.

Code:
ptr += *siz; *ptr = 0; ptr -= len;

What do I win?
Logged

Offline Offline
God Member
*****
Karma: 17
Posts: 522
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ah, but in all seriousness, let's think through your problem. I think the problem you're running into is that when you try to put all the statements together, you're losing your reference back to ptr. Let's say that ptr is in memory location 10 and your string is starting at memory location 20 and has a length of 5.

Code:
*(ptr += *siz) = 0;

Should work fine. (ptr += *siz) updates memory location 10 by adding siz to it. So memory location 10 used to hold the value 20; now it holds the value 25. That operation completes and returns the value assigned, which is 25. So the parentheses evaluate to 25. Now we have:

Code:
*25 = 0;

And that works fine. *25 causes the program to look in memory location 25 and then we assign that location the value 0. Now here's the key: WHAT IS RETURNED FROM THAT OPERATION?
« Last Edit: December 19, 2013, 02:44:36 am by joshuabardwell » Logged

SF Bay Area (USA)
Offline Offline
Tesla Member
***
Karma: 124
Posts: 6652
Strongly opinionated, but not official!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
        uint64_t len = strlen (str); /* length of incoming string */
Really?  You're just a glutton for punishment!

Code:
        ptr += *siz; /* move pointer to end of re-allocated buffer */
        *ptr = 0; /* null terminate last character */
        ptr -= len; /* move pointer to start of newly allocated area */
I don't think you can do it.  You are pretty much restricted to one assignment per statement, except for what you can accomplish with ++ and -- (neither of which will what you want.)

You can only do x += y or x = y if x is an actual variable with an address; you can't do if x is an expression (whose result is probably some temporary location.)

You DO realize that the terseness of your source code has very little to do with the efficiency of the code that the compiler will produce, right?

Hmm.  The compiler let me do pinMode(led+=4, OUTPUT);
I think I find that ... disturbing.  I really hope that you can't do (ptr-=len)[len+*siz] = 0;
(OMG, it did compile...)
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 291
Posts: 25847
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I think I find that ... disturbing.  I really hope that you can't do (ptr-=len)[len+*siz] = 0;

One of my favourite C "quirks"
Code:
int array [10] = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0};

void setup()
{
  int index = 3;
  Serial.begin (9600);
  Serial.println (index [array]);
}

void loop()
{}
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Worst state in America
Offline Offline
God Member
*****
Karma: 32
Posts: 792
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
        uint64_t len = strlen (str); /* length of incoming string */
Really?  You're just a glutton for punishment!

I originally tested the "print to buffer" code in 64 bit Linux (GCC). I wanted to see how much it could take. I had a check for the malloc/realloc failing and I kept on pumping strings at it while watching my memory pool (ram and swapfile).

Finally it failed because I overran the uint32_t I was using, so I switched it to uint64_t and blasted it more.

It ran and ran until it ate up all my ram, all my swapfile and a little while longer, then finally the realloc() failed by returning a NULL.

I looked at my swap partition with a hex editor raw and found 16 gigabytes of "This is a test" filling it!

I kept on adding zeros to the test loop... I had something like "for x=0; x < 10000000000; x++" I lost track of how many zeros I had.

Anyway, that's why I had uint64_t in there... and I forgot to change it back to a more sane uint16_t for my Arduino use.  smiley
Logged

Gentlemen may prefer Blondes, but Real Men prefer Redheads!

Worst state in America
Offline Offline
God Member
*****
Karma: 32
Posts: 792
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ah, but in all seriousness, let's think through your problem. I think the problem you're running into is that when you try to put all the statements together, you're losing your reference back to ptr. Let's say that ptr is in memory location 10 and your string is starting at memory location 20 and has a length of 5.

Code:
*(ptr += *siz) = 0;

Should work fine. (ptr += *siz) updates memory location 10 by adding siz to it. So memory location 10 used to hold the value 20; now it holds the value 25. That operation completes and returns the value assigned, which is 25. So the parentheses evaluate to 25. Now we have:

Code:
*25 = 0;

And that works fine. *25 causes the program to look in memory location 25 and then we assign that location the value 0. Now here's the key: WHAT IS RETURNED FROM THAT OPERATION?

I see what you mean... and it clearly explains why I couldn't do what I thought I should be able to do. Thanks for the clear explanation!

-- Roger
Logged

Gentlemen may prefer Blondes, but Real Men prefer Redheads!

Offline Offline
Edison Member
*
Karma: 32
Posts: 1389
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

C/C++ has a defined type for buffer lengths, size_t.
Logged

Pages: [1] 2   Go Up
Jump to: