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
schnarf
Jun 1, 2002
I WIN.

Vanadium posted:

I meant something that is to %d as %s is to %c :(

You can read in a single integer, say, 12345, and use the modulus and integer division operators to read out digits.

Adbot
ADBOT LOVES YOU

Dijkstracula
Mar 18, 2003

You can't spell 'vector field' without me, Professor!

schnarf posted:

You can read in a single integer, say, 12345, and use the modulus and integer division operators to read out digits.
Or, you know, sprintf.

code:
        int i;
        char buffer[7];

        scanf("%d", &i);
        if (i >= 10e5) {
                printf("Number too large to fit in six bytes (inc \0 terminator)!\n");
                exit(1);
        }

        sprintf(buffer, "%d", i);

        for (i = 0; i < 6; i++) {
                if (!buffer[i]) break;
                printf("%d: %c\n", i, buffer[i]);
        }

        return 0;
code:
$ ./a.out
13254
0: 1
1: 3
2: 2
3: 5
4: 4
I guess we're still not sure about what he's precisely trying to do. Read in multiple, delimited integers? Or extract digits from a integer?

Dijkstracula fucked around with this message at 01:42 on Aug 23, 2009

fritz
Jul 26, 2003

6174 posted:

give enough information so that a researcher, who will almost certainly have minimal programming experience, can still access the data or hand the program off to someone to update it so they can access the data.

A simple thing to do is to include some kind of reference file with a readme describing exactly what your code's supposed to do on it, that way future scientist can tell if they need to have someone do more thinking.

6174
Dec 4, 2004

fritz posted:

A simple thing to do is to include some kind of reference file with a readme describing exactly what your code's supposed to do on it, that way future scientist can tell if they need to have someone do more thinking.

That is already done. However, you assume to much. In my experience such additional files are completely ignored.

fritz
Jul 26, 2003

6174 posted:

That is already done. However, you assume to much. In my experience such additional files are completely ignored.

OK, make an auxiliary program that calls your i/o code and prints out "Everything's OK with the data!" or "There's a problem with this installation, go find a programmer". If you're really paranoid, make it so whenever you open any file you check the reference file for validity.

slovach
Oct 6, 2005
Lennie Fuckin' Briscoe
I tried spawning a thread, the parameter was a struct being passed by reference.

One of the members of the struct is a pointer to another struct, which I'm trying to set the address to, why do I get an access violation when I try to write to it?

If I just create the struct globally or locally within the thread I don't have issues.


Also I just figured out I can debug and make changes to injected dll's within visual studio. :aaa:

Zakalwe
May 12, 2002

Wanted For:
  • Terrorism
  • Kidnapping
  • Poor Taste
  • Unlawful Carnal Gopher Knowledge

slovach posted:

I tried spawning a thread, the parameter was a struct being passed by reference.

One of the members of the struct is a pointer to another struct, which I'm trying to set the address to, why do I get an access violation when I try to write to it?

If I just create the struct globally or locally within the thread I don't have issues.


Also I just figured out I can debug and make changes to injected dll's within visual studio. :aaa:

Race condition. By the time the thread fires up and tries to read the struct, the stackframe it was created in was already destroyed. Calls to create a thread don't return when the thread has read its parameters and started. They can return pretty much immediately before all that happens, depending on the scheduler.



You're doing something like this I guess
code:
foo()
{
       params p;

       start_thread(bar, p);
}

bar(params& p)
{

}

Execution you're expecting

p created on stack
start_thread called
bar thread created
bar starts
bar uses p
foo exits destroying stack frame containing p.


What's happening

p created on stack
start_thread called
bar thread created
foo exits destroying stack frame containing p.
bar starts
bar uses p


or

p created on stack
start_thread called
bar thread created
bar starts
foo exits destroying stack frame containing p.
bar uses p


You can solve this a number of ways. Using a global p, using any type of barrier mechanism after the start_thread that the thread itself deactivates after it has read its parameters etc.

slovach
Oct 6, 2005
Lennie Fuckin' Briscoe
Thanks for the explanation. :)

Zakalwe
May 12, 2002

Wanted For:
  • Terrorism
  • Kidnapping
  • Poor Taste
  • Unlawful Carnal Gopher Knowledge
I'm trying to find out if the method for returning a const reference to a local is defined by the standard or if it's implementation dependent

code:
const bar& foo()
{
    bar b;
    return b;
} 

int main()
{
    const bar& i = foo();
}
It would make sense that b/i is actually created on the caller's stack and passed by reference internally to foo(). Of course a copy could be done, but that would seem dumb.

I've taken a look at sections 3.8 and 8.3.2 and I'm not seeing anything. Anybody?

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh

Zakalwe posted:

I'm trying to find out if the method for returning a const reference to a local is defined by the standard or if it's implementation dependent

That will only ever work if you get lucky. It's basically the canonical example of why you don't ever do that. Constness means nothing in that case.

You may also want to read about return-value optimization. You may also also want to stop trying to outsmart your compiler.

An example:
code:
#include <iostream>
#include <string>
using namespace std;

struct bar
{
    bar(int i) : i(i) {}

    void print() const
    {
        cout << i << endl;
    }

    int i;
};

const bar& foo()
{
    bar b(123);
    return b;
}

const bar& oof()
{
    bar b(321);
    return b;
}

int main()
{
    const bar& i = foo();
    i.print();
    oof();
    i.print();
}
code:
~$ g++ -o fun fun.cpp
fun.cpp: In function ‘const bar& foo()’:
fun.cpp:19: warning: reference to local variable ‘b’ returned
fun.cpp: In function ‘const bar& oof()’:
fun.cpp:25: warning: reference to local variable ‘b’ returned
~$ ./fun 
123
321

Avenging Dentist fucked around with this message at 00:11 on Aug 25, 2009

Vanadium
Jan 8, 2005

Are you trying to do the lifetime extension thing?

code:
bar foo()
{
    bar b;
    return b;
} 

int main()
{
    const bar& i = foo();
    // foo's b is copied and i is holding on to the copy and keeping it alive
}

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh

Vanadium posted:

Are you trying to do the lifetime extension thing?

That's for temporaries. (§12.2)

Zakalwe
May 12, 2002

Wanted For:
  • Terrorism
  • Kidnapping
  • Poor Taste
  • Unlawful Carnal Gopher Knowledge
Yes, that's what I want. Reading now.

edit: I know RVO. Thought this could replace it.

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh

Zakalwe posted:

Yes, that's what I want. Reading now.

No it is not. Lifetime extension of temporaries via reference is not an optimization strategy. It is just a feature that falls out from making things like the following work "sensibly":

code:
int foo(const std::string &s)
{
    // uses s in some interesting and magical way
}

// ...

foo("hello"); // creates std::string temporary

Zakalwe posted:

edit: I know RVO. Thought this could replace it.

By all means, go ahead and try to outsmart both 1) compiler writers who have mostly resolved this with RVO and named RVO, and 2) standards writers who added support for move semantics in C++0x to resolve this in other situations.

Zakalwe
May 12, 2002

Wanted For:
  • Terrorism
  • Kidnapping
  • Poor Taste
  • Unlawful Carnal Gopher Knowledge
Ahh OK, that makes perfect sense. I thought I had found an exception to the rule, a special case where it was OK to return a reference to a local and that this was allowed by the standard. By replace it, I meant that I could use it in place of RVO in my existing code.

In my specific codebase I need to get the normal at a specific point on a triangle from barycentric values.

what I currently do is something like this.

code:
Normal n;
t.get_normal(n, u, v);
Something like

code:
const Normal& n = t.get_normal(u, v);
was what I was hoping I could do based on my misunderstanding of the standard. Neater looking, no copy, n is const. Oh well. I'll stick to RVO.

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh

Zakalwe posted:

was what I was hoping I could do based on my misunderstanding of the standard. Neater looking, no copy, n is const. Oh well. I'll stick to RVO.

Use RVO. Every commercial compiler supports it.

Kei
Mar 18, 2004
Extreme Suckability
Is sendto() a non-blocking operation?

I ask because I'm trying to make a UDP-based application that buffers the packets at the application level rather than in the kernel because I want to be able to remove packets from the queue in certain circumstances.

My idea was to make the socket write buffer really small (the minimum being 2KB) so that only a packet or two would fit in there at a time. I would then use select() to wait for the buffer to open up enough for me to write a new packet.

However, it seems that select() returns immediately even if several packets have already been put in the socket buffer. Perhaps I'm just not going about this correctly. Any tips on achieving this would be greatly appreciated.

haveblue
Aug 15, 2005



Toilet Rascal

Kei posted:

Is sendto() a non-blocking operation?

I ask because I'm trying to make a UDP-based application that buffers the packets at the application level rather than in the kernel because I want to be able to remove packets from the queue in certain circumstances.

My idea was to make the socket write buffer really small (the minimum being 2KB) so that only a packet or two would fit in there at a time. I would then use select() to wait for the buffer to open up enough for me to write a new packet.

However, it seems that select() returns immediately even if several packets have already been put in the socket buffer. Perhaps I'm just not going about this correctly. Any tips on achieving this would be greatly appreciated.

You can explicitly request a nonblocking socket from socket(), which will never block but instead cause socket calls to return an error immediately.

HondaCivet
Oct 16, 2005

And then it falls
And then I fall
And then I know


ffffffffffff why did they give me this job need help again

I got all of it to compile and whatnot but now I've got another problem. I am building this project off of some examples from the Boost.Asio tutorials (client and server). These guys just make timestamps and send them from the server to the client. I want this thing to send data from an instrument from the server to the client in a continuous streaming fashion. First, I have just been trying to get it to send a large set number of data points. I first experimented by just altering the tutorial code I posted send 10000 timestamps instead of just one. Just a simple for loop got it to do that, it was easy. However, when I try to do it with my instrument's code worked in, it only posts a single data point and then quits. I am using the whole, original client program from the tutorial and I have transplanted the server part in with my instrument's initialization/data-taking program. I debugged it a bit and caught the client's EOF error catcher ending the client app too early but even when I comment it out, I only get one point and the client just hangs instead. I have pastebinned the part of the server program that actually reads the instrument, plops the data into part of a char array and is supposed to send it out. Some of the code in here is from the instrument but you will probably be able to tell what isn't C++ or Boost stuff. If you can't, let me know.

To me, at least, the only difference the client should be seeing is that the original code sends a string and in my code, it's sending a character sequence from an array (which is what a string is, isn't it?). Do any of you guys see where the client might be getting caught, where the server stops sending new points, etc.?

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh

HondaCivet posted:

ffffffffffff why did they give me this job need help again

You're destroying the socket and recreating it every time you try to write something to it. You should create it once (when the client initiates a connection - if this is one-to-one communication, do it at the beginning of your snippet) and then reuse that until you're done.

HondaCivet
Oct 16, 2005

And then it falls
And then I fall
And then I know


Avenging Dentist posted:

You're destroying the socket and recreating it every time you try to write something to it. You should create it once (when the client initiates a connection - if this is one-to-one communication, do it at the beginning of your snippet) and then reuse that until you're done.

I thought it might be something like this but I can't see where it's destroying the old socket. Is it in the code I posted?

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh

HondaCivet posted:

I thought it might be something like this but I can't see where it's destroying the old socket. Is it in the code I posted?

http://pastebin.com/m4e53daa8

Kei
Mar 18, 2004
Extreme Suckability

sex offendin Link posted:

You can explicitly request a nonblocking socket from socket(), which will never block but instead cause socket calls to return an error immediately.

Well I guess I asked the wrong question. sendto() seems to be non-blocking.

However, it seems that sendto() doesn't care if there's space in the socket for the data to go. I guess that makes sense since UDP doesn't guarantee delivery.

But what I'd like to be able to do is tell if a socket's send buffer can take the next packet I want to put in. If I make the socket's write buffer only 2KB, I can't really put another full packet into the send buffer until the one currently in the buffer is gone. Is there some way to find out how much of a socket's send buffer is currently being used?

HondaCivet
Oct 16, 2005

And then it falls
And then I fall
And then I know


Avenging Dentist posted:

http://pastebin.com/m4e53daa8

I just started taking socket stuff out of the for loop until it worked, thanks! You are like SA's own personal CS lab TA. :swoon:

BigRedDot
Mar 6, 2008

I'd like to know if there is a way to force ld to not discard unused weak symbols?

For instance, consider:

main.cc:
code:
int main( ) { }
foo.cc:
code:
#include "bar.hh"

Bar b = Bar( );
bar.hh:
code:
#include <iostream>

class Bar {
public:
    Bar( ) { std::cout << "Bar" << std::endl; }
};
If I compile and link all the object files together explicitly, I get the expected result:
code:
foz% g++ -c -o foo.o foo.cc
foz% g++ -c -o main.o main.cc
foz% g++ main.o foo.o
foz% ./a.out
Bar
foz%
However, if I build foo.o into a static archive first, it does not work:
code:
foz% g++ -c -o foo.o foo.cc
fox% ar -r libfoo.a foo.o
foz% g++ -c -o main.o main.cc
foz% g++ main.o -L. -lfoo
foz% ./a.out
foz%
i.e., it does not call the Bar ctor and there is no "Bar" symbol in a.out, it's just completely discarded. "Bar" does show up in foo.o, but as a weak symbol. I'm trying to use static initialization of some throw-away objects to register some prototype objects with a global static registry instance. I'd like the prototypes to just "be available" to anyone that links to this library, and I'd like other people to be able to contribute prototypes to the registry easily in the same way.

Is there any way to make this happen? I am aware of --whole-archive, but there's not really any way to shoehorn that into our nightmare home-grown build system. This code will always be linked in as a static archive, and there's no way to add per-archive flags. So any solution really has to be in the source. I've tried various ideas, like making them static member variables, but no success with that either.

Oh, gcc 4.1.2, btw (RHEL5 stock).

Contero
Mar 28, 2004

Why does the syntax for switch have to suck so freaking bad? I feel like I run into a lot of situations where a switch would be useful, but it's so ugly that I end up using if-else instead.

It's mainly because of the break keyword. I usually want to do a switch to make my code more concise and eliminate a bunch of var == 1 || var == 21 || var == 624 code, but having to stick break after each chunk of code puts me roughly even.

Why can't switch look something like this:
code:
switch (variable) {
   case(one, two, three) { code; }
   case(52542) { 
      more code;
      bla bla bla;
      if (something) break;
      bla bla;
   }
   default { eat an rear end; }
}
I'd die and go to heaven if C++ had this. It seems like something that could be done with some template and preprocessor magic like boost::foreach.

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh

HondaCivet posted:

I just started taking socket stuff out of the for loop until it worked, thanks! You are like SA's own personal CS lab TA. :swoon:

Hopefully you put the following immediately after creating the acceptor object:
code:
tcp::socket socket(io_service);
acceptor.accept(socket);
Incidentally, if you wanted to have multiple (serial) connections to this, you'd wrap everything after creating the acceptor with an infinite loop (that's the infinite loop from the Boost.Asio server example).

csammis
Aug 26, 2003

Mental Institution

Contero posted:

Why can't switch look something like this:
code:
switch (variable) {
   case(one, two, three) { code; }
   case(52542) { 
      more code;
      bla bla bla;
      if (something) break;
      bla bla;
   }
   default { eat an rear end; }
}

How does your syntax handle fall-through?

code:
switch (var)
{
  case 1:
    do_some_pre_op();
  case 2:
  case 3:
    do_some_op();
    break;
  case 4:
    do_some_other_op();
    break;
}

HondaCivet
Oct 16, 2005

And then it falls
And then I fall
And then I know


Avenging Dentist posted:

Hopefully you put the following immediately after creating the acceptor object:
code:
tcp::socket socket(io_service);
acceptor.accept(socket);
Incidentally, if you wanted to have multiple (serial) connections to this, you'd wrap everything after creating the acceptor with an infinite loop (that's the infinite loop from the Boost.Asio server example).

Yes, it did not work until I added that stuff right after.

Since I've already got a reply open, I'll just ask now . . . I'd like to include a little I/O on this thing so that transfer can be shut off with a text command. Would it be possible to include that on client side somehow or would it have to go on the server? Also, a problem of putting it on the client side, at least in its current configuration, is that the client app window constantly has crap being written to it so I'm not sure how you'd enter text. Can you open a second window somehow?

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh

BigRedDot posted:

I'd like to know if there is a way to force ld to not discard unused weak symbols?

Pretty sure that's not what's happening (EDIT: oh, maybe you and I mean the same thing). ld ignores object files in static libraries if they can't be used to resolve any missing symbols in your regular object files. The previous sentence also implies the solution to this problem (reference something - anything - from bar.cc in foo.cc).

Assuming you are also including a header file, the simple solution is:

code:
// bar.h
extern int a_special_symbol;
static int nothing = a_special_symbol;



// bar.cc
int a_special_symbol = 420;



// foo.cc
#include "bar.h"

int main() {}

Avenging Dentist fucked around with this message at 23:28 on Aug 25, 2009

Contero
Mar 28, 2004

csammis posted:

How does your syntax handle fall-through?

code:
switch (var)
{
  case 1:
    do_some_pre_op();
  case 2:
  case 3:
    do_some_op();
    break;
  case 4:
    do_some_other_op();
    break;
}

Well it doesn't, but I'd argue that fall-through is lame anyway.

code:
if (var == 1)
  do_some_pre_op();

switch (var)
{
  case (1,2,3) 
  { 
    do_some_op();
  }
  case (4) 
  {
    do_some_other_op();
  }
}

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh

Contero posted:

Well it doesn't, but I'd argue that fall-through is lame anyway.

If you don't need fallthrough, why are you using a switch statement? That's basically why they exist. You're trying to take away the one useful feature of a language construct because you don't like writing "else if".

csammis
Aug 26, 2003

Mental Institution

Contero posted:

Well it doesn't, but I'd argue that fall-through is lame anyway.

You're right, two comparisons are better than one!

And what AD said about this being why switch statements are useful in the first place.

BigRedDot
Mar 6, 2008

Avenging Dentist posted:

Pretty sure that's not what's happening (EDIT: oh, maybe you and I mean the same thing). ld ignores object files in static libraries if they can't be used to resolve any missing symbols in your regular object files. The previous sentence also implies the solution to this problem (reference something - anything - from bar.cc in foo.cc).

Assuming you are also including a header file, the simple solution is:

code:
// bar.h
extern int a_special_symbol;
static int nothing = a_special_symbol;



// bar.cc
int a_special_symbol = 420;



// foo.cc
#include "bar.h"

int main() {}
Well, that works without the static declaration (and fails with it, it seems to try the copy before a_special_symbol is initialized). But I'd swear I already tried exactly this at work already... different OS and compiler at home, I guess we'll find out tomorrow!

BigRedDot
Mar 6, 2008

BigRedDot posted:

Well, that works without the static declaration (and fails with it, it seems to try the copy before a_special_symbol is initialized). But I'd swear I already tried exactly this at work already... different OS and compiler at home, I guess we'll find out tomorrow!

Wow, really weird. When I try the test code at work, it only works at work if I *do* have the static. I did notice that had I added a member variable in the test code, and that it does not function without it (my real code had no member data, just a constructor that does something). So I added some useless std::string state data to my real code. Now it segfaults with the static present, just like the test code does at home, and does nothing at all without it. C++ static initialization, grrr...

Just for reference, when I run it through gdb, with breakpoints on the ctor I supply, and on the default copy ctor, the problem occurs in the copy constructor. It is trying to initialize the static variable, but it has not yet created the extern that it is copying from.

edit: but if I make the dummy member data an int instead of a string, the real code works and no longer segfaults...

editedit: and as long as there is one static variable declared, all the other externs also workm even wthout corresponding static decalarations

BigRedDot fucked around with this message at 13:42 on Aug 26, 2009

Lexical Unit
Sep 16, 2003

How could a call to std::map<std::string, int>::erase(const std::string&) cause a SIGBUS? I could understand a call to std::map<std::string, int>::erase(iterator) causing it if the iterator was invalid, but that's not what I'm seeing. The problem is intermittent and not easily reproducible.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
Two possibilities. First, you might be passing in a bad reference that's produced in some unreliable, rarely-taken code path; tracking the provenance of the reference is your best bet there, assuming you can't reproduce the crash in a debugger. Second, you might have logically-unrelated memory corruption for any of the myriad reasons that's possible in C++. Good luck.

haveblue
Aug 15, 2005



Toilet Rascal

Avenging Dentist posted:

That's basically why they exist.

I thought they existed because until very recently compilers were not smart enough to detect good places to generate jump tables automatically and switch was how you explicitly requested one.

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh

sex offendin Link posted:

I thought they existed because until very recently compilers were not smart enough to detect good places to generate jump tables automatically and switch was how you explicitly requested one.

The one is a consequence of the other.

Adbot
ADBOT LOVES YOU

HondaCivet
Oct 16, 2005

And then it falls
And then I fall
And then I know


Is there a way to take in input without causing the program to hang? I'd like the program to check for input each time it runs through a loop but, of course, it waits for input instead of continuing through the loop. I'm using plain old cin (C++ here with Boost). What else could I do?

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