Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
ANIME AKBAR
Jan 25, 2007

afu~
I'm now teaching myself C for the purpose of programming microcontrollers. I want to write to members of a structure in a sequential fashion, and I want to do this in a loop where the index points to each member.

So for example, I have a structure:
code:
typedef struct {
   char a;
   char b;
   char c;
   char d;
   char e;
} examplestruct_t;
And I want to assign a=1, b=2, c=3, d=4, e=5 (in my example I have a lot more members, which is why I want to do it in a loop rather than assigning them each manually).

I've learned about how pointers can address members directly, but I haven't found any examples of how the member being pointed to can be decided by a variable.

In my mind it looks like this:
code:
main (void) {
   examplestruct_t examplestruct, *examplepoint;
   examplepoint=&examplestruct;
   for (char i=0,i<sizeof(examplestruct),i++) {
      *examplepoint+i=i;   //in my head, examplepoint has the base address of examplestruct and that is incremented by i in order to point to each member.
   }
}
But I know this is completely wrong. I just haven't seen an example of someone doing it in a way I can understand.

And I do have a good reason for using a structure instead of an array; it would really help later in the code to pull member values by member names, not index numbers.

Can anyone set me straight?

Thanks in advance

ANIME AKBAR fucked around with this message at 03:20 on Nov 6, 2011

Adbot
ADBOT LOVES YOU

nielsm
Jun 1, 2009



You could do something like this:
code:
char *fieldptr = &thestruct.a;
int counter = 0;
for (; fieldptr < &thestruct.e; ++fieldptr)
  *fieldptr = counter++;
This requires all the fields to be of the same type, of course.

(I can't remember if you can actually do less-than comparisons on pointers like that. Use a different loop condition if you can't.)

ANIME AKBAR
Jan 25, 2007

afu~

nielsm posted:

You could do something like this:
code:
char *fieldptr = &thestruct.a;
int counter = 0;
for (; fieldptr < &thestruct.e; ++fieldptr)
  *fieldptr = counter++;
This requires all the fields to be of the same type, of course.

(I can't remember if you can actually do less-than comparisons on pointers like that. Use a different loop condition if you can't.)

Hmm, that's actually pretty close to what I was trying. At least yours compiles, which is more than I can say for my own attempts. It's interesting that you define *fieldptr as a char instead of as the structure type it's pointing to... maybe that's the key.

However I can't really confirm it works... my programming environment can only debug code by actually programming the hardware, then stepping through the code and reading the actual registers. And the compiler always optimizes away all the pointers somehow so I can't see their values... is there a decent, free compiler/debugger that will allow me to try out little snippets of code like this one?

yippee cahier
Mar 28, 2005

Another way to get around this is by using an array and then defining the friendly names for the indexes. You'll probably find examples of something like this in your microcontroller headers for memory mapped hardware addresses. i.e. PORTB will be defined as it's address in memory. I saw some code that used an enum for this which was neat as the author threw in an extra enum value that functioned as the size of the array:
code:
enum es_enum {
    ES_A,
    ES_B,
    ES_C,
    ES_D,
    ES_E,
    ES_COUNT
}
typedef struct {
   char[5] chars;
} examplestruct_t;
examplestruct es;

/* either use this: */
for (i=0; i< ES_COUNT; i++)
    es.chars[i] = i;

/* or this: */
es.chars[ES_C] = 0x55;
I don't know, looks nice and clear to me, but I've been screwing around with this stuff for too long.

nielsm
Jun 1, 2009



You could also define your struct with an inner union. Technically the behaviour of this is undefined but in practice it tends to do exactly what you expect.

code:
typedef struct {
  union {
    char chars[5];
    struct {
      char a, b, c, d, e;
    };
  };
} examplestruct_t;
I believe that should allow you to use either foo.chars[3] or foo.d for the same value.

Bonfire Lit
Jul 9, 2008

If you're one of the sinners who caused this please unfriend me now.

ANIME AKBAR posted:

It's interesting that you define *fieldptr as a char instead of as the structure type it's pointing to
It isn't pointing to the structure, it's pointing to the first field of the structure (thestruct.a). That is because the structure member access is evaluated before taking the address, i.e. it's parsed &(thestruct.a), and a is a char.
Now, (void*)&thestruct == (void*)&thestruct.a, but since you took the address of its first member, you should still consider the variable to be pointing to the member, not the struct itself.

csammis
Aug 26, 2003

Mental Institution

ANIME AKBAR posted:

However I can't really confirm it works... my programming environment can only debug code by actually programming the hardware, then stepping through the code and reading the actual registers. And the compiler always optimizes away all the pointers somehow so I can't see their values... is there a decent, free compiler/debugger that will allow me to try out little snippets of code like this one?

Can you get the asm output? I've been doing this exact thing on an MSP430 and just examining the GCC assembly output to make sure I didn't do something wrong with unions since I haven't used them in years. I'd expect to see the base address of the union or struct or whatever loaded into a register and then writes to offsets from that register in the data size you're using.

code:
typedef union _WWVBBuffer
{
    unsigned char data[8];
    struct
    {
        unsigned short seg0;
        unsigned short seg1;
        unsigned short seg2;
        unsigned short seg3;
    } segments;
} WWVBBuffer;

void shiftleft(WWVBBuffer* pBuf)
{
    asm ( "clrc" );
    pBuf->segments.seg3 <<= 1;
    pBuf->segments.seg2 <<= 1;
    pBuf->segments.seg1 <<= 1;
    pBuf->segments.seg0 <<= 1;
    pBuf->segments.seg3 |= 0x0100;
    pBuf->segments.seg3 &= 0xFFF0;
}

int main()
{
    WWVBBuffer buf;

    buf.segments.seg0 = 0x8004;
    buf.segments.seg1 = 0x0100;
    buf.segments.seg2 = 0x2203;
    buf.segments.seg3 = 0x0310;

    shiftleft(&buf);
    ...
}
The shiftleft function compiles down to
code:
0000f834 <shiftleft>:
    f834:	12 c3       	clrc			
    f836:	1e 4f 06 00 	mov	6(r15),	r14	;0x0006(r15)
    f83a:	0e 5e       	rla	r14		
    f83c:	9f 5f 04 00 	rla	4(r15)		;0x0004(r15)
    f840:	04 00 
    f842:	9f 5f 02 00 	rla	2(r15)		;0x0002(r15)
    f846:	02 00 
    f848:	af 5f 00 00 	add	@r15,	0(r15)	;0x0000(r15)
    f84c:	3e d0 00 01 	bis	#256,	r14	;#0x0100
    f850:	3e f0 f0 ff 	and	#-16,	r14	;#0xfff0
    f854:	8f 4e 06 00 	mov	r14,	6(r15)	;0x0006(r15)
    f858:	30 41       	ret
where r15 is holding the address in pBuf

You might also want to haunt the embedded programming nanothread and the C/C++ megathread.

csammis fucked around with this message at 17:07 on Nov 6, 2011

raminasi
Jan 25, 2005

a last drink with no ice
Just so I'm clear - there isn't any portable way to do what he's asking, right? I'm sure there are plenty of things that will work, but there's nothing that must work?

pseudorandom name
May 6, 2007

Nope. I think there's a guarantee that struct members are located in memory in the order they're declared, but there's nothing said about any padding between members.

nielsm
Jun 1, 2009



pseudorandom name posted:

Nope. I think there's a guarantee that struct members are located in memory in the order they're declared, but there's nothing said about any padding between members.

Well, since there is also a guarantee that every bit in memory can be accessed through a char, casting the a pointer to the first member to a char pointer and then reading sizeof(thestruct) chars forward you will also access all of the memory the struct occupies, of course that includes any padding inserted.
Is this even relevant to anything? I forgot.

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed

GrumpyDoctor posted:

Just so I'm clear - there isn't any portable way to do what he's asking, right? I'm sure there are plenty of things that will work, but there's nothing that must work?

Well there's some dumb options:
code:
typedef struct examplestruct {
    char a;
    char b;
    char c;
    char d;
    char e;
    char f;
} examplestruct;

#define O(f) offsetof(examplestruct, f)
static size_t examplestruct_offsets[] = { O(a), O(b), O(c), O(d), O(e), O(f) };
#undef O

void dostuff() {
    examplestruct example;
    for (int i = 0; i < 6; ++i) {
        ((char *)&example)[examplestruct_offsets[i]] = foo();
    }
}

csammis
Aug 26, 2003

Mental Institution

GrumpyDoctor posted:

Just so I'm clear - there isn't any portable way to do what he's asking, right? I'm sure there are plenty of things that will work, but there's nothing that must work?

The essence of microcontroller programming :madmax:

Internet Janitor
May 17, 2008

"That isn't the appropriate trash receptacle."
If you don't have any requirements for portability, you already have to document the hell out of your code for future generations to understand it, performance/size are at a premium and you're bending over backwards to deal with the abstractions of C, why don't you just write assembly?

csammis
Aug 26, 2003

Mental Institution

Internet Janitor posted:

If you don't have any requirements for portability, you already have to document the hell out of your code for future generations to understand it, performance/size are at a premium and you're bending over backwards to deal with the abstractions of C, why don't you just write assembly?

If "crazy C tricks" constitute 0.1% of the code then it is still worth learning C for the other 99.9% that doesn't have to be written in assembly.

TasteMyHouse
Dec 21, 2006
There's always inline assembly, or linking against object files originating from assembly.

HKBGUTT
May 7, 2009


A question about POSIX thread-programming:

I have a application where a thread (A) spawns two children-threads (B and C). Then i want to cancel thread C from thread B.

I set cancel state in thread C using:
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL);
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);

Then i want to cancel the thread using:
pthread_cancel(idC);

I know that using Cancel is bad practice, but that is not really important.

The problem is that when i call cancel from thread B thread C will not cancel, even though i have set several cancellation points using testcancel. If i call cancel from thread A thread C cancels emediatealy, when calling from thread B nothing happens.

finaleph
Oct 11, 2011

Are you sure the children threads are running in parallel and that the canceltype and cancelstate in C are set before B calls cancel?

ryo
Jan 15, 2003
If a web server returns:

code:
reply: 'HTTP/1.1 200 OK\r\n'
header: Content-Length: 5218
header: Content-Type: application/atom+xml; type=feed
header: Server: Microsoft-HTTPAPI/1.0
header: Date: Wed, 09 Nov 2011 11:33:56 GMT
after requesting an XML Atom feed, does the lack of ETag/Last-Modified imply that I can't do any kind of caching with the results?

Zombywuf
Mar 29, 2008

ryo posted:

If a web server returns:

code:
reply: 'HTTP/1.1 200 OK\r\n'
header: Content-Length: 5218
header: Content-Type: application/atom+xml; type=feed
header: Server: Microsoft-HTTPAPI/1.0
header: Date: Wed, 09 Nov 2011 11:33:56 GMT
after requesting an XML Atom feed, does the lack of ETag/Last-Modified imply that I can't do any kind of caching with the results?

You can almost always cache unless the server explicitly tells you not to (usually this will be for privacy reasons). However, what you should do in this case is next time you display the content to the user you should send a request for the data with an If-Not-Modified-Since header with the value from the Date header you received. If you get a 304 in response you can use the cached value.

ryo
Jan 15, 2003

Zombywuf posted:

You can almost always cache unless the server explicitly tells you not to (usually this will be for privacy reasons). However, what you should do in this case is next time you display the content to the user you should send a request for the data with an If-Not-Modified-Since header with the value from the Date header you received. If you get a 304 in response you can use the cached value.

Unfortunately it's still giving me 200 status :/
I know that the document hasn't changed.
Perhaps I should continue in the Python thread?

quote:

>>> h = httplib2.Http('.cache')
>>> response, content = h.request('http://w.x.y.z:8090/publications-api/publications/14715',headers={'If-Not-Modified-Since':'Wed, 09 Nov 2011 14:34:08 GMT'})
send: 'GET /publications-api/publications/14715 HTTP/1.1\r\nHost: w.x.y.z:8090\r\nuser-agent: Python-httplib2/$Rev$\r\naccept-encoding: gzip, deflate\r\nif-not-modified-since: Wed, 09 Nov 2011 14:34:08 GMT\r\n\r\n'
reply: ''
connect: (w.x.y.z, 8090)
send: 'GET /publications-api/publications/14715 HTTP/1.1\r\nHost: w.x.y.z:8090\r\nuser-agent: Python-httplib2/$Rev$\r\naccept-encoding: gzip, deflate\r\nif-not-modified-since: Wed, 09 Nov 2011 14:34:08 GMT\r\n\r\n'
reply: 'HTTP/1.1 200 OK\r\n'
header: Content-Length: 5218
header: Content-Type: application/atom+xml; type=feed
header: Server: Microsoft-HTTPAPI/1.0
header: Date: Wed, 09 Nov 2011 14:35:56 GMT
>>> response.fromcache
False

Zombywuf
Mar 29, 2008

ryo posted:

Unfortunately it's still giving me 200 status :/
I know that the document hasn't changed.
Perhaps I should continue in the Python thread?

Sorry, that should be "If-Modified-Since". If the server returns 200 it means one of two things:

1) The resource has changed.

2) The server does not support If-Modified-Since.

http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html Section 14.25 for reference.

ryo
Jan 15, 2003
Thanks, I tried with If-Modified-Since and it still returned status 200. I'll contact the people that run the webserver to see what they say about it.

Mindisgone
May 18, 2011

Yeah, well you know...
That's just like, your opinion man.
I am coding html and I have a regular text link that I want to open a seperate page in a presized new window. That is not the problem, my problem is it's opening the new window in an obscure position on the screen and I would rather the new window open up in the center of the screen. I have seen countless javascript solutions to this problem but I want to avoid java at all costs if I can. If html/css cannot handle this on it's own perhaps there is a php solution availible? Here is what's there now:

<body link="#FC6767" vlink="#FFF2AD" alink="#336699">
<div id="login"><a href="cwerklogin.html" target="popup" onclick="window.open('cwerklogin.html', 'popup', 'width=850,height=400'); return false" title="login">Login / Register > it's free!</a></div>

nielsm
Jun 1, 2009



Mindisgone posted:

I am coding html and I have a regular text link that I want to open a seperate page in a presized new window. That is not the problem, my problem is it's opening the new window in an obscure position on the screen and I would rather the new window open up in the center of the screen. I have seen countless javascript solutions to this problem but I want to avoid java at all costs if I can. If html/css cannot handle this on it's own perhaps there is a php solution availible? Here is what's there now:

<body link="#FC6767" vlink="#FFF2AD" alink="#336699">
<div id="login"><a href="cwerklogin.html" target="popup" onclick="window.open('cwerklogin.html', 'popup', 'width=850,height=400'); return false" title="login">Login / Register > it's free!</a></div>

:supaburn: "I don't wanna use Javascript!"
:supaburn: *goes ahead and uses javascript*

See that part with onclick=""? That's Javascript in the quotes.

If you want to size and position browser windows like that you have to use client side scripting. A PHP script can't interactively control what happens on the user's screen, it can just send HTML* to the client.

I'm pretty sure I would dislike getting a new window for logging in, but it probably depends on what exactly you want to do. Either way, you should probably change the target="popup" to target="_blank" to get a new, unnamed browser window, instead of using a window with the name "popup".

*PHP can send any kind of data to the client, but the client has to send a request to the server first.

TasteMyHouse
Dec 21, 2006
Also Java != Javascript.

Mindisgone
May 18, 2011

Yeah, well you know...
That's just like, your opinion man.
It's not that I dislike java I'm just really inexperianced and will only start learning it after I pick up mysql but thank you for clearing that up I will straighten this out and add the necessary javascript.

:tipshat:

edit: I think it's worth mentioning, in case popular opinion is against me on this cause I'm open for suggestion, I want the main page to stay up the way it is so when people click the login link and login in the popup closes and the main page changes only the slightest to let the user know they're logged in and keep the focus on the main page. Maybe this is me just being too lazy to create a seperate page but it seems to flow well enough.

Mindisgone fucked around with this message at 22:16 on Nov 9, 2011

raminasi
Jan 25, 2005

a last drink with no ice
Java and JavaScript are completely different languages. They have different styles, different origins, and different places in the serving-content-to-users process.

Mindisgone
May 18, 2011

Yeah, well you know...
That's just like, your opinion man.
I didn't feel like writing javascript sorry for being lazy

:bang:

nielsm
Jun 1, 2009



Mindisgone posted:

I didn't feel like writing javascript sorry for being lazy

:bang:
If you want to abbreviate Javascript, write JS. Even shorter than Java!


Anyway, consider what purpose you are serving by opening a new window for the user to enter his login, as opposed to just sending him to a new page, having a login box visible on every page, or having one made visible on the current page when the user clicks a link/button.
Consider that if you open a new window for getting login credentials you will either have to keep opening new pages after the login has been processed in that window, or you will have to somehow transfer "control" back to the original window.
Consider popup-blockers, some people still use very aggressive ones.
Consider that users (still) get confused by new windows popping up on top of others.

I would suggest having your login simply be a separate page linked to without opening new windows or having dynamic flyouts or such, but make sure you include a "return address" functionality: A way to pass an URL the user should be redirected back to after logging in. That can be surprisingly useful.

Shaocaholica
Oct 29, 2002

Fig. 5E
How do I edit the tab complete behavior in a shell? Specifically bash on OS X?

I'm used to this behavior:

-single tab on no input matches anything in the cwd. If the cwd has only 1 item it will insert that. If it has many items with a common prefix it will insert the prefix.
-single tab on any amount of input matches and auto fills anything in PATH and cwd regardless of if its executable or not

Shaocaholica fucked around with this message at 00:53 on Nov 10, 2011

Scaramouche
Mar 26, 2001

SPACE FACE! SPACE FACE!

Mindisgone posted:

I didn't feel like writing javascript sorry for being lazy

:bang:

I've actually been using floating DIVs for this kind of thing with some success. The secret is to only trigger on a user event; user clicks on something, they expect something to happen. Don't link it to onload or a timer or something like that because you'll just freak people out.

Check out the discussion here:
http://stackoverflow.com/questions/345987/how-to-create-a-javascript-floating-div-signup-form

On the lighter side, I ran into a nasty one today. You visit the page, are looking around. About 30 seconds later a livechat window opens up and a 'representative' starts asking you questions. The best part? There's no button to close the live chat window, so it just sits there with its questions unanswered... haunting. Intrusive as hell and probably pretty scary to the uninformed user.

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!
Are there still legit uses for exceptions outside of the normal error reporting side of things? I just walked away from a programmer fight over something like this:

code:
// Let's see if this class implements IProjectDoesSomething
try
{
   IProjectDoesSomething foo = (IProjectDoesSomething) someObject;
   foo.bar()
}
catch(Exception)
{
   // Observe the exception is unhandled
}
They were trying to convince me it was more efficient than "probing the interface," which I suspect they're meaning to be a virtual table walk. But doesn't it have to look at the virtual table anyways in the cast? And they convenient ignore the cost of unwinding the call stack, generating the stack trace, and potentially notifying any attached debuggers.

The worst part to me is it's C#, where you could just use the "is" operator and move on.

I found later some of the background behind the wacky arguments was that some of them were told it was legit--or at least apropos to the task at hand--to use exceptions in some odd cases that weren't necessarily related to error handling. I don't get it myself, and I can't think of any examples.

It also doesn't acknowledge why they just blindly take the exception, when foo.bar() just as well could have a problem. Let's not go there. It was a fun day.

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.
You know, maybe that code was once more sane, but profiling indicated that it was a performance bottleneck and it was rewritten to this less idiomatic but faster version.

However, since that's almost certainly not what happened, that is indeed a coding horror in C#.

(In general, what exceptions are used for depends a lot on the language, and to some extent on the libraries themselves. Python, for instance, uses exceptions to indicate when to stop enumerating something. In Apple's Objective-C code, exceptions are not for error reporting but for unrecoverable errors (yes, you're really not supposed to catch them).)

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!

pokeyman posted:

You know, maybe that code was once more sane, but profiling indicated that it was a performance bottleneck and it was rewritten to this less idiomatic but faster version.

However, since that's almost certainly not what happened, that is indeed a coding horror in C#.

(In general, what exceptions are used for depends a lot on the language, and to some extent on the libraries themselves. Python, for instance, uses exceptions to indicate when to stop enumerating something. In Apple's Objective-C code, exceptions are not for error reporting but for unrecoverable errors (yes, you're really not supposed to catch them).)
I assure you that this code has never, ever been profiled.

Now I have to look up that Python exception handling style because that sounds kind of goofy to me.

Sedro
Dec 31, 2008
C# even supports as so you only need to perform the "probing" once.
Good:
code:
if (someObject is IProjectDoesSomething)
{
    var foo = (IProjectDoesSomething)someObject;
    foo.bar();
}
Better:
code:
var foo = someObject as IProjectDoesSomething;
if (foo != null)
{
    foo.bar();
}
What the gently caress are you doing (I see this all the time):
code:
if (someObject is IProjectDoesSomething)
{
    var foo = someObject as IProjectDoesSomething;
    foo.bar();
}

Jonnty
Aug 2, 2007

The enemy has become a flaming star!

Rocko Bonaparte posted:

Now I have to look up that Python exception handling style because that sounds kind of goofy to me.

It uses them for error handling too of course. It's just that when you care a bit less about performance, exceptions become convenient to use for other things and you can afford to take a bit more of a "try and see" approach. Sounds a bit weird, but it often ends up cleaner in the long run - you're doing what you want to do first then dealing with potential problems afterwards.

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!

Sedro posted:

C# even supports as so you only need to perform the "probing" once.
Good:
code:
if (someObject is IProjectDoesSomething)
{
    var foo = (IProjectDoesSomething)someObject;
    foo.bar();
}
Better:
code:
var foo = someObject as IProjectDoesSomething;
if (foo != null)
{
    foo.bar();
}
What the gently caress are you doing (I see this all the time):
code:
if (someObject is IProjectDoesSomething)
{
    var foo = someObject as IProjectDoesSomething;
    foo.bar();
}

I do actually like the crazy method there for being the easiest on the eyes, but for it to be best overall, I would have to assume that it can optimize the two lookups. You'd think that would be something it could do at the byte code level, before the runtime even gets its mittens on it. I don't know if that happens though.

Sointenly
Sep 7, 2008
A buddy of mine is creating a .bat and is a hard time with a particular aspect.

He is writing a DOS test which queries the total disk space of a particular drive letter, and then runs a series of reads / writes / and compares until the disk is completely full.

The problem he's having is querying the disk space and then converting that output into a manageable number which can them be put back into the .bat

For instance, lets say you had a 1TB disk "E".

From dos: E > "Dir" which would return "1099511627776 Bytes Free" Assuming the disk was empty.

What he needs to do is then take that output, convert it to TB's and then be able to plug that result back into a the batch.

He is claiming that the byte integer is just too large to work with...


If anyone has any suggestions on simple ways we could go about this I'd really appreciate it. We were thinking of some sort of exe that could do the calculation and then created an output which can be called by dos... but we're not sure if that's the way to go.

TasteMyHouse
Dec 21, 2006
You should use a real scripting language, like Python or Ruby. Or Powershell.

Adbot
ADBOT LOVES YOU

Sointenly
Sep 7, 2008

TasteMyHouse posted:

You should use a real scripting language, like Python or Ruby. Or Powershell.

The actually test has been in place for some time as a .bat, so we're just trying to add some functionality to it without having to reinvent the wheel.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply