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
hooah
Feb 6, 2006
WTF?

Hughlander posted:

It's just a hack Id expect a TA to find clever. By treating the bool as an int with true being nonzero and false being zero if any return is false you are multiplying by zero and now the bool will always be false for the rest of the operations.

But why not just set result to the return from the function? That seems an overly-complicated way of going about things.

Adbot
ADBOT LOVES YOU

baby puzzle
Jun 3, 2011

I'll Sequence your Storm.
Its called bad programming.

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

hooah posted:

But why not just set result to the return from the function? That seems an overly-complicated way of going about things.
It might have been a holdover from a previous version where it was done iteratively, to give maximum benefit of the doubt. And then the reason not to do it more readably as result = (result && doingstuff()) could be that doingstuff is not a const function, and this way would go "if the result is already false then the rest of the calls don't even happen". Using *= will still make the calls.

Not to suggest it's a good idea still, you'd probably get the exact same performance, or even better, doing something less opaque and without causing warnings, like
bool x=doingstuff(); result=(result&&x);

And none of this is relevant to the actual code as given which is doing *= on declaration, so it's using an undefined value as the first argument. Hopefully that was shorthand to tell us that result was a bool, rather than the actual code?

hooah
Feb 6, 2006
WTF?

roomforthetuna posted:

And none of this is relevant to the actual code as given which is doing *= on declaration, so it's using an undefined value as the first argument. Hopefully that was shorthand to tell us that result was a bool, rather than the actual code?

Yes, I was including the type in that line, although result was declared earlier.

Qwertycoatl
Dec 31, 2008

roomforthetuna posted:

Not to suggest it's a good idea still, you'd probably get the exact same performance, or even better, doing something less opaque and without causing warnings, like
bool x=doingstuff(); result=(result&&x);

Or just
code:
result = doingstuff() && result;

OneEightHundred
Feb 28, 2008

Soon, we will be unstoppable!

FamDav posted:

Second, aliasing rules work on types, not memory locations.
Right, but my question is whether doing a[1] would make the compiler consider it to be part of an aggregate (i.e. of type A[]) and consequently be an alias, because an array of A can't contain a B, while the second one would only be attempting to access a pointer to A and not an array element, or if there's no difference?

Edited the example to fix it.

FamDav
Mar 29, 2008
Again,

Some dude, possibly the same one posted:

C99 6.5 7:

An object shall have its stored value accessed only by an lvalue expression that has one of the following types:
— a type compatible with the effective type of the object,
— a qualified version of a type compatible with the effective type of the object,
— a type that is the signed or unsigned type corresponding to the effective type of the object,
— a type that is the signed or unsigned type corresponding to a qualified version of the effective type of the object,
— an aggregate or union type that includes one of the aforementioned types among its members (including, recursively, a member of a subaggregate or contained union), or
— a character type.

An aggregate type does not change things.

OneEightHundred
Feb 28, 2008

Soon, we will be unstoppable!
Right, A and B::a fit that rule, but my concern is that A[] and B don't. i.e. I don't think this wouldn't work:
code:
struct D
{
    A a1;
    A a2;
};

int func3(D *d, const B *b, int c)
{
    d->a2.value = c;
    return b[1].a.value;
}
... because while d->a2 and b[1].a are compatible, *d and *b aren't, so it can assume that an assignment to an object of type D won't be visible in an object of type B. Would a[1] do the same thing by implying that it exists within an object of type A[]?

OneEightHundred fucked around with this message at 01:39 on Jan 13, 2014

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
Subscript syntax — and pointer arithmetic in general — doesn't say anything for aliasing purposes about the base having array type. And anyway, there's a rule that, for the purposes of pointer arithmetic, a singleton object is interchangeable with an array of length 1.

However, you're technically correct anyway that the l-values can't alias, but it's not because of the type-aliasing rules; it's because a pointer to a hypothetical element before an array is not a valid pointer into the array, and pointer arithmetic is undefined on an invalid pointer.

I don't know of any compiler that does that analysis, though, and it would be problematic in practice because of offsetof tricks.

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!
I figured out in my home project that the CSV file I'm trying to read in, at the size of roughly 32MB, takes 60 seconds to load. I profiled it in VTune and found out I was heavily I/O bound. It was something like only 5-10% of the run time could be pegged to actual CPU cycles. So sure, I'm reading a file off the disk, but half a meg per second on my desktop doesn't really explain that. I'm kind of saddened by the lack of some standard CSV loader, or at least a cross-platform one, but I guess that fits within the culture.

The core of what I first wrote uses an ifstream for the file in question, and calls std::getline() to read off each line. I was assuming a good first in-place optimization would be to replace this with slurping the file and working off it in memory. I guess there are a lot of caveats to that. I ultimately got the contents into a preallocated char* and get a stream handle off that, after a few attempts that were just acting like middlemen and were causing the file stream to still arbitrarily seek. I also hear ifstream has a buffer anyways, and then I read that none of the standard streams do any buffering by defaults. Now I have no clue.

At this point I wonder what I can do to try to minimize that I/O overhead. I assume if I get it into memory I shouldn't have any more file I/O overhead; I haven't confirmed that in a new profile yet. I also kind of wonder about streams in VS2010. Should I drop back to the C library? Should I jump forward into Boost?

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
Profilers often have some ability to trace syscalls and I/O requests so you can figure out if e.g. you're doing a ton of small reads behind the scenes.

crazypenguin
Mar 9, 2005
nothing witty here, move along
Try the suggestion in this question: http://stackoverflow.com/questions/9371238/why-is-reading-lines-from-stdin-much-slower-in-c-than-python

hooah
Feb 6, 2006
WTF?
I'm having trouble overloading a function. One is void foo(vector<int> &v) and the other is void foo(vector<int> &v, int a, int b) and MSVC is complaining that when I call foo(v, 0, static_cast<int>(v.size() - 1)) "the function does not take 3 arguments".

Moon Wizard
Dec 29, 2011

hooah posted:

I'm having trouble overloading a function. One is void foo(vector<int> &v) and the other is void foo(vector<int> &v, int a, int b) and MSVC is complaining that when I call foo(v, 0, static_cast<int>(v.size() - 1)) "the function does not take 3 arguments".

I just tried this out with VS2012 and it worked fine for me. Are you sure both the functions are in the same scope? If it was just an argument mismatch you should get an error message mentioning overloaded functions, but since you're not I think you're running into something like this.

hooah
Feb 6, 2006
WTF?

DaVideo posted:

I just tried this out with VS2012 and it worked fine for me. Are you sure both the functions are in the same scope? If it was just an argument mismatch you should get an error message mentioning overloaded functions, but since you're not I think you're running into something like this.

I think I missed the scope part of the equation. I'll just rename one of them.

Computer viking
May 30, 2011
Now with less breakage.

Rocko Bonaparte posted:

I figured out in my home project that the CSV file I'm trying to read in, at the size of roughly 32MB, takes 60 seconds to load. I profiled it in VTune and found out I was heavily I/O bound. It was something like only 5-10% of the run time could be pegged to actual CPU cycles. So sure, I'm reading a file off the disk, but half a meg per second on my desktop doesn't really explain that. I'm kind of saddened by the lack of some standard CSV loader, or at least a cross-platform one, but I guess that fits within the culture.

The core of what I first wrote uses an ifstream for the file in question, and calls std::getline() to read off each line. I was assuming a good first in-place optimization would be to replace this with slurping the file and working off it in memory. I guess there are a lot of caveats to that. I ultimately got the contents into a preallocated char* and get a stream handle off that, after a few attempts that were just acting like middlemen and were causing the file stream to still arbitrarily seek. I also hear ifstream has a buffer anyways, and then I read that none of the standard streams do any buffering by defaults. Now I have no clue.

At this point I wonder what I can do to try to minimize that I/O overhead. I assume if I get it into memory I shouldn't have any more file I/O overhead; I haven't confirmed that in a new profile yet. I also kind of wonder about streams in VS2010. Should I drop back to the C library? Should I jump forward into Boost?


The last time I did something like that, I made my own caching wrapper around read() (that read a MB at the time), and pulled a char at the time out of that. It felt very much like reinventing the wheel, but it worked nicely.

hooah
Feb 6, 2006
WTF?
While hacking together a quicksort algorithm from the book, I came across this bit of code. Here, i starts at the left element in the array, and j starts at one before the last element.
code:
for (;;){
	while (v[++i] < pivot){}
	while (pivot < v[--j]){}
	if (i < j)
		std::swap(v[i], v[j]);
	else
		break;
}
I figured I could get rid of the for loop and make a while with an anded condition:
code:
while (v[++i] < pivot && pivot < v[--j]) {
	if (i < j)
		mySwap(v[i], v[j]);
	else
		break;
}
However, this doesn't end up sorting the array. I should have known I couldn't out-smart the book, but why doesn't my "improvement" work?

hooah fucked around with this message at 22:48 on Jan 16, 2014

nielsm
Jun 1, 2009



First, your indentation is horrible. It doesn't match the code structure in any sensible way.

Second, try first rewriting the code to not use pre-increment tricks and empty loop bodies and conditions. It might make it clearer what it is doing:
C++ code:
bool more_to_sort = true;
while (more_to_sort) {
  // find the next early value greater than the pivot
  do {
    i++;
  } while (v[i] < pivot);
  // find the next late value less than the pivot
  do {
    j--;
  } while (pivot < v[j]);
  // check if they are mutually sorted
  // (here v[i] >= v[j] due to the above two loops)
  if (i < j)
    // they are in wrong order, swap them
    std::swap(v[i], v[j]);
  else
    // they are in correct order respective to the pivot
    // and by induction so are all other values considered.
    // no more to do for this pivot and range.
    more_to_sort = false;
}
Compare the behaviour of that reformulation to that of your own attempt.

E: You can also do away with the more_to_sort flag without having to resort to empty loop conditions and a break. In fact it's quite explicit what the real condition for the loop to end is. See if you can spot it.

nielsm fucked around with this message at 22:48 on Jan 16, 2014

hooah
Feb 6, 2006
WTF?
Ah, I think I see. The difference has to do with the while loop bodies being empty, yes?

Also, sorry about the indentation; I copied the code from Visual Studio, and Chrome made enormous tabs that I didn't completely fix. I shall do that now.

DarkJC
Jul 6, 2010
So I'm not sure if this is the right thread to ask this, but here's some background.

I'm trying to use a C library for graphs called igraph. I downloaded the source of the newest stable version, and compiled it properly on my system without errors (as far as I know).

The problem is that although I can compile code that uses the library successfully, the functionality of the library appears to be broken.

Below is the simple test code I'm using:

pre:
#include <igraph.h>

int main(int argc, char* argv[]) 
{
    igraph_t g;

    igraph_empty(&g, 0, 1);

    printf("vcount: %d\n", igraph_vcount(&g));
    printf("ecount: %d\n", igraph_ecount(&g));

    if (igraph_vcount(&g) != 0) {
        return 1;
    }

    if (igraph_ecount(&g) != 0) {
        return 2;
    }

    igraph_destroy(&g);

    return 0;
}
Basically it creates an empty graph with 0 vertices and 0 edges and then attempts to verify that the graph actually has 0 vertices and 0 edges, super basic. Unfortunately igraph_vcount returns a seemingly random number that definitely is nowhere near 0. Heres the output of the last few runs:

pre:
vcount: 1335272576
ecount: 0

vcount: -1973136176
ecount: 0

vcount: -1321827856
ecount: 0

vcount: -556353632
ecount: 0

vcount: 1584473680
ecount: 0

As you can see, ecount is fine, but vcount is nowhere near 0. I've searched google and the official mailing list for the library and no one seems to mention any problem like this (which makes sense to me really because no one would use it if it was this broken)

Here's how I'm compiling it in gcc:

pre:
gcc -g -ansi -Wall -Iinclude/igraph -Llib -ligraph main.c -o main
The header files are in include/igraph and the compiled library is in lib of course.

My question is, am I missing something stupid? Some GCC flag that I'm missing or one I'm using that could be messing things up? Some issue with 64-bit Fedora running in a VM that I'm unaware of? I just want to know what the next step would be to troubleshoot this further other than posting on the mailing list I guess. I don't really want to do anything more with this library until I fix this problem.

ephphatha
Dec 18, 2009




It looks like you're getting an uninitialised variable somewhere. Try checking the value of g.n (since that's all igraph_vcount() does) immediately before and after calling igraph_empty() and see if the value changes.

Edgar Allen Pwn
Dec 31, 2013
i don't know if anyone here can help me, but i've been spinnin my wheels on this for a good few hours now.

what i'm trying to implement:
http://www.roguebasin.com/index.php...ngeon_Generator

what i've got:
http://pastebin.com/Nh9t76G8

i'm trying to build a 2d array of objects, whose type has a member describing a rectangle (with endpoint and dimensions)
so far the "container" objects seem to work just fine. they print as expected.

as for the "rooms" within each object in the array, only the first element (top left, 0,0) ever prints.

i have no idea why and it's driving me nuts. any help would be greatly appreciated.

hooah
Feb 6, 2006
WTF?
First question: My C++ prof told us that memory you allocate with new and then forget to delete creates a memory leak, but when your program terminates, all memory allocated to the program (including what you forgot to de-allocate) gets returned. My software design prof says the memory doesn't get returned until you reboot your computer. Is this OS-dependent, or is one of them wrong?

Second: Is there a way to create say 10 variables of the same type and name them something like thing1 through thing10 without copying the same line 10 times? I'm guessing probably not.

Bonfire Lit
Jul 9, 2008

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

hooah posted:

First question: My C++ prof told us that memory you allocate with new and then forget to delete creates a memory leak, but when your program terminates, all memory allocated to the program (including what you forgot to de-allocate) gets returned. My software design prof says the memory doesn't get returned until you reboot your computer. Is this OS-dependent, or is one of them wrong?
Your software design prof is wrong. All modern OSes will reclaim memory a process has allocated when that process exits. (This may be different on lovely embedded OSes where the memory manager is terrible, but all desktop and smartphone/tablet operating systems will reclaim.)

hooah posted:

Second: Is there a way to create say 10 variables of the same type and name them something like thing1 through thing10 without copying the same line 10 times? I'm guessing probably not.
You create use an array of 10 ints (or any other type) by writing int thing[10];. Then you can access those variables with thing[0] through thing[9].

Bonfire Lit fucked around with this message at 15:07 on Jan 25, 2014

baby puzzle
Jun 3, 2011

I'll Sequence your Storm.
This is how you learn that some professors will say things that are literally wrong and probably don't care to learn otherwise.

shrughes
Oct 11, 2008

(call/cc call/cc)

hooah posted:

First question: My C++ prof told us that memory you allocate with new and then forget to delete creates a memory leak, but when your program terminates, all memory allocated to the program (including what you forgot to de-allocate) gets returned. My software design prof says the memory doesn't get returned until you reboot your computer. Is this OS-dependent, or is one of them wrong?

It's free to be used once the process dies. If you ask the OS for the right to use some memory, it's going to keep track of which processes can see that memory, and once there are no processes using a particular piece of memory, it will know that memory can be used for something else.

It's not OS-dependent if you're talking about operating systems where "rebooting" your computer is an actual thing. You could theoretically make an OS and standard library where it was true, of course, but if your hardware supports the notion of memory protection that would be extremely silly.

hooah posted:

Second: Is there a way to create say 10 variables of the same type and name them something like thing1 through thing10 without copying the same line 10 times? I'm guessing probably not.

Make an array of size 10.
code:
int thing[10] = { 0 };
If you really want them to be _variables_ then the answer would be no, unless you create some satanic preprocessing library that might be covered upthread.

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

hooah posted:

My software design prof says the memory doesn't get returned until you reboot your computer. Is this OS-dependent, or is one of them wrong?
I think Windows 3.1 was the last time this was true of a major user-level OS. But while he's wrong, he's kind of right from the perspective of software design - you should be designing code as if that's true, not just leaking everywhere 'til your program shuts down.

Deep Dish Fuckfest
Sep 6, 2006

Advanced
Computer Touching


Toilet Rascal

roomforthetuna posted:

I think Windows 3.1 was the last time this was true of a major user-level OS. But while he's wrong, he's kind of right from the perspective of software design - you should be designing code as if that's true, not just leaking everywhere 'til your program shuts down.

It's more than "should", it's "must", because new and delete do more than allocate and deallocate memory. They also call constructors and destructors. So if you don't call delete on an object because its memory will get freed when your program exits, and that object is, say, buffering things before writing them to disk, then it won't be able to flush its buffers as it most likely normally would in its destructor, and you've just lost some data.

DarkJC
Jul 6, 2010

Ephphatha posted:

It looks like you're getting an uninitialised variable somewhere. Try checking the value of g.n (since that's all igraph_vcount() does) immediately before and after calling igraph_empty() and see if the value changes.

Thanks for such a fast reply, sorry I couldn't respond sooner. Here's what I get from that:

pre:
g.n before igraph_empty: 0
g.n after igraph_empty: 0
vcount: -579552
ecount: 0
So g.n is always 0 before and after. Seems like igraph_vcount is grabbing a different (probably uninitialized) value somehow. I'm still confused as the library appeared to successfully compile.

DarkJC fucked around with this message at 20:26 on Jan 25, 2014

The Laplace Demon
Jul 23, 2009

"Oh dear! Oh dear! Heisenberg is a douche!"
Here's the relevant definition:
code:
igraph_integer_t igraph_vcount(const igraph_t *graph) {
  return graph->n;
}
Are you using the latest version? You might be linking against an old version of the library? Here's what happens when I compile and run your code.

code:
~/igraph-0.6.5 $ ./configure && make
~ $ clang -Iigraph-0.6.5/include igraph-0.6.5/src/.libs/libigraph.a test.c -o test
~ $ ./test
vcount: 0
ecount: 0

shrughes
Oct 11, 2008

(call/cc call/cc)
Now a coworker wants to put using std::string; and using std::vector; and using boost::variant; and some others in a common utils.hpp header file. What's the best way to shut this movement down?

Plorkyeran
Mar 22, 2007

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

roomforthetuna posted:

I think Windows 3.1 was the last time this was true of a major user-level OS. But while he's wrong, he's kind of right from the perspective of software design - you should be designing code as if that's true, not just leaking everywhere 'til your program shuts down.
Depends on what you're doing. In short-lived command line programs that don't use much memory, all that explicitly freeing data does is slow you down (and in the case of dmd, switching to a memory allocator that doesn't even support freeing reduced memory usage in addition to doubling speed). For longer-running applications you obviously can't just leak memory endlessly, but suppressing calls to free during shutdown means that you don't have to page all of your application's stuff back into ram when the user tries to free up some ram by exiting your application. Your destructors definitely don't get a chance to run when the user kills your application via task manager because trying to exit normally results in their hard drive grinding for five minutes.

Blotto Skorzany
Nov 7, 2008

He's a PSoC, loose and runnin'
came the whisper from each lip
And he's here to do some business with
the bad ADC on his chip
bad ADC on his chiiiiip

shrughes posted:

Now a coworker wants to put using std::string; and using std::vector; and using boost::variant; and some others in a common utils.hpp header file. What's the best way to shut this movement down?

Brain them.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
Sure, but the design of "never free mmeory" can bite you later. Trying to reuse the parser or lexer in a static analyzer tool or the codegen in a JIT will bite you in the rear end if it never frees memory.

gcc has some atrocious use-after-free errors if you try to actually use it to compile more than one compilation unit at a time. Take a guess why David Malcolm's JIT branch hasn't updated for a while.

shrughes
Oct 11, 2008

(call/cc call/cc)

I think I've managed to derail it into a compromise of telling them to do it inside non-global namespaces.

Blotto Skorzany
Nov 7, 2008

He's a PSoC, loose and runnin'
came the whisper from each lip
And he's here to do some business with
the bad ADC on his chip
bad ADC on his chiiiiip

Suspicious Dish posted:

gcc has some atrocious use-after-free errors if you try to actually use it to compile more than one compilation unit at a time. Take a guess why David Malcolm's JIT branch hasn't updated for a while.

Is this related to their hodgepodge of memory management schemes (last I remember, they have a mix of gc, refcounting, obstacks and bespoke implementations of malloc/free; wonder if that's still the case?)

Plorkyeran
Mar 22, 2007

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

Suspicious Dish posted:

Sure, but the design of "never free mmeory" can bite you later. Trying to reuse the parser or lexer in a static analyzer tool or the codegen in a JIT will bite you in the rear end if it never frees memory.
The parser and codegen and such should be implemented as a library whose allocator is supplied by the client, and the library should call free; it's just that in the short-lived CLI tool the supplied free function is a no-op.

That Turkey Story
Mar 30, 2003

shrughes posted:

I think I've managed to derail it into a compromise of telling them to do it inside non-global namespaces.

I think that's fine. We do this in some places -- in our code we use C++11 and boost, and often there are similar-but-different libraries (thread-related stuff, smart pointers, time, etc.). To make it easy to change what what we use at a later point and to prevent us from having to qualify the types/templates in certain namespaces, we bring them in via using-declarations in headers.

Bruegels Fuckbooks
Sep 14, 2004

Now, listen - I know the two of you are very different from each other in a lot of ways, but you have to understand that as far as Grandpa's concerned, you're both pieces of shit! Yeah. I can prove it mathematically.

shrughes posted:

Now a coworker wants to put using std::string; and using std::vector; and using boost::variant; and some others in a common utils.hpp header file. What's the best way to shut this movement down?

We are not allowed to use "using" full stop!

Adbot
ADBOT LOVES YOU

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed
That's definitely an overreaction. Locally scoped using statements can significantly improve readability in some cases, and they're sometimes the only way to get the correct semantics (e.g. for swap).

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