|
hooah posted:How does one go about putting function declarations in an .h file, the function definitions in a .cpp, then the main program in another .cpp? I've done this with classes, but this seems to be different (and should be, if I understand my professor correctly). The obvious wrong thing with that code is that you're using stuff from the std namespace in the header, but the using statements are after the header inclusion. The lazy way to fix this is to move the header inclusion down; the correct way is to slather std:: all over the place in the header (and include the appropriate stdlib headers in the .h).
|
# ? Oct 16, 2013 22:19 |
|
|
# ? Jun 9, 2024 01:49 |
|
Plorkyeran posted:It mostly isn't. Ok, it looks like that helped a lot. My one remaining question is how do I deal with the default parameter in split? I tried removing the sep = ' ' bit from the declaration in the .h, but then VS complains that split doesn't take 2 arguments. If I leave sep = ' ' in, I'm told that the default parameter is getting redefined.
|
# ? Oct 16, 2013 22:33 |
|
"Using cmph is quite simple. Take a look: *ten lines of allocs and adapters and configurators*" Library writers need to learn that libraries are supposed to solve problems.
|
# ? Oct 16, 2013 23:00 |
|
Grocer Goodwill posted:
The examples are actually mostly configuration. C++ code:
|
# ? Oct 16, 2013 23:11 |
|
hooah posted:Ok, it looks like that helped a lot. My one remaining question is how do I deal with the default parameter in split? I tried removing the sep = ' ' bit from the declaration in the .h, but then VS complains that split doesn't take 2 arguments. If I leave sep = ' ' in, I'm told that the default parameter is getting redefined. The declaration should have the default parameter, not the definition (which happens to tell you a lot about how default parameters are implemented in C++).
|
# ? Oct 16, 2013 23:15 |
|
Plorkyeran posted:The declaration should have the default parameter, not the definition (which happens to tell you a lot about how default parameters are implemented in C++). If I do that, I get a couple of linking errors: code:
|
# ? Oct 16, 2013 23:49 |
|
A strange(to me) thing just happened. code:
edit: I never use the return string, just the value, so it wasn't causing me any problems. edit edit: There was a warning, it was just buried in a list of conversion warnings- I'm an idiot. bobua fucked around with this message at 00:57 on Oct 17, 2013 |
# ? Oct 17, 2013 00:39 |
|
bobua posted:A strange(to me) thing just happened. "Not all code paths return a value" is just a level 1 warning, it won't stop a compile. You can configure your project to not compile if the code has warnings, you can also set pragmas to ignore warnings.
|
# ? Oct 17, 2013 00:53 |
|
Not returning when the function has a return type is undefined behavior IIRC. Visual Studio will give you an error if no paths return a value but I don't think the complier is obligated to do anything. It will also refuse to compile this which may be wrong C++ code:
|
# ? Oct 17, 2013 03:05 |
|
So I've just got back to Uni and in one class we had to clear the screen to a colour using a memcpy to set every pixel. The "obvious" way was two nested for loops:code:
|
# ? Oct 19, 2013 22:07 |
|
What's a good way to store/read config settings in a file? I was looking at yaml-cpp but that seems to need boost but if I use boost, I could probably use program-options. Suggestions?
|
# ? Oct 19, 2013 22:30 |
|
Didn't realize Visual Studio 2013 was officially released a couple of days ago. I didn't think it was coming out until mid November.
|
# ? Oct 19, 2013 23:10 |
|
Praseodymi posted:So I've just got back to Uni and in one class we had to clear the screen to a colour using a memcpy to set every pixel. The "obvious" way was two nested for loops: It goes much faster with x on the inside because of the processor caches. When you write your pixel to memory, it doesn't go to memory immediately, it goes into the L1 (then L2) cache, which can batch up 16/128/whatever bytes of writes to send off to memory at once. This works much better if you're writing adjacent memory locations instead of jumping to locations screenWidth apart. I'm not sure exactly what you're doing in the last part - what's i?
|
# ? Oct 20, 2013 00:07 |
Qwertycoatl posted:It goes much faster with x on the inside because of the processor caches. When you write your pixel to memory, it doesn't go to memory immediately, it goes into the L1 (then L2) cache, which can batch up 16/128/whatever bytes of writes to send off to memory at once. This works much better if you're writing adjacent memory locations instead of jumping to locations screenWidth apart. A: C++ code:
B: C++ code:
Hybrid A+B: C++ code:
|
|
# ? Oct 20, 2013 00:19 |
|
I would try the obvious:C++ code:
C++ code:
|
# ? Oct 20, 2013 00:40 |
|
That won't work if the image has a stride.
|
# ? Oct 20, 2013 00:42 |
|
pseudorandom name posted:That won't work if the image has a stride. It also assumes that pixels isn't something like void* or char*. Details...
|
# ? Oct 20, 2013 00:45 |
|
Praseodymi posted:So I've just got back to Uni and in one class we had to clear the screen to a colour using a memcpy to set every pixel. The "obvious" way was two nested for loops: Post the C and assembly for each version. Where exactly are your writes going to? Actual memory-mapped device memory will have very different cache behavior from normal memory and I doubt you're actually dealing with it since you would need to be in the kernel. This is what gcc -O3 spits out for me (I'm pleasantly surprised that it's smart enough to realize that an actual call to memcpy() is dumb for just 4 bytes): A: code:
code:
If you wanted to make it even faster, the next thing I would do is start unrolling the loops. In both versions, each pass through the inner loop does one pixel's worth of useful work and one add, compare, and branch. You can do better than that by setting more than one pixel per loop iteration. Say you have 1024 pixels to set. You can split it into two loops, one that sets 100 pixels at each iteration that runs 10 times to cover 1000 pixels and then one that sets one per iteration that runs 24 times. The loop overhead will be a much smaller percentage of the total time. Performance will increase as the amount set per loop increases up to the point where the loop no longer fits in the CPU's instruction cache. Of course if you know the array sizes at compile time, the most efficient version of all is something with no loops either using rep instructions or just a bunch of mov's in a row. And none of this will ever matter in real code unless you're doing stuff like writing image filters.
|
# ? Oct 20, 2013 06:20 |
|
This is all from memory as I'm currently stood outside the New Look changing rooms, so sorry if it's incorrect but I hope you'll get the gist of it. Basically, we were given a pointer to the first pixel of the screen, and each pixel has four bytes, RGB and alpha. the fastest method was doing the two nested for loops with y at the top and x inside, and then doing a memcpy to at screenPointer + 4 * (x + y * screenWidth) of the 4 values we wanted to use for that pixel. Seeing as it was one contiguous block of memory and the x and y values were just for readability I'd just done code:
If this still doesn't make sense I can look at the actual code when I get home.
|
# ? Oct 20, 2013 12:21 |
Praseodymi posted:This is all from memory as I'm currently stood outside the New Look changing rooms, so sorry if it's incorrect but I hope you'll get the gist of it. If that's how the actual loop condition was written, yeah I'm not too puzzled if it's slower. Keep in mind that the loop condition (here, i < screeWidth * screenHeight *4) is evaluated for every iteration. The compiler might not be able to optimise the right-hand side of the < to a constant expression for whatever reason. So you are still doing multiplications for each pixel here, and it's in a comparison operation, not memory address operation. As far as I can tell from the disassembly Foxfire_ posted, the A version actually compiled to something similar to what I wrote as the hybrid A+B, in that it calculates a row start pointer before each inner loop and then increments that as a "current pixel" pointer inside the inner loop. The really important part is that it uses the x86 addressing modes to do the multiplications for pointer calculation, it doesn't use an actual multiplication instruction even once. The addressing modes are faster than arithmetic multiplication, but have a few limitations. Meanwhile, the disassembly for the B version does a single (arithmetic) multiplication, outside the loop, and then only does incrementing of a "current pixel index" inside the loop. That should be fast, even more so if the loop is unrolled. Same for the A version disassembly. The A version is much longer since it ends up using several more registers, which mean the compiler had to add a prologue and epilogue to save those on the stack first. But both of those disassebles are of course the result of an optimising compilation, a naive compilation would probably have looked much different. Returning back to your version, I think it's slow because either you compiled it without optimisations, or otherwise the optimiser couldn't figure out what you were doing in the loop condition and ended up doing arithmetic multiplications every iteration.
|
|
# ? Oct 20, 2013 13:29 |
|
Hmm, that's a good point actually, I think they were both compiled using Visual Studio's debug settings. I'll try it in release and see the difference, thanks.
|
# ? Oct 20, 2013 14:01 |
|
I'm not that great at C; is there some way I can declare a struct to be global such that multiple threads see the same struct? I'm trying to implement a mutex with test_and_set. I can get the mutual exclusion pretty easily, but I'm having trouble guaranteeing fairness. The mutex has a simple queue which is basically an array plus a size counter, a head position, and a tail position (and of course the array is protected by a spinlock using test and set). Basically, if thread A tries to get the mutex while thread B is currently using the mutex, then thread A will stick itself in the queue by adding itself to array[tail], increment tail, and then increment the size. Within the context of thread A, it seems like that works, A goes in the queue, and the queue size goes up. However, when thread B finishes, it still has a queue size of 0; even though it should ostensibly be accessing the same queue, it's not seeing the same size. I've tried declaring all the attributes of the queue (size, head, tail) to be volatile, and it still doesn't seem to work. Threads should be sharing memory; can anybody explain why each thread has an inconsistent view of the same struct? Here's my queue struct, for reference code:
code:
|
# ? Oct 21, 2013 16:11 |
|
You are passing the struct by value, so you are only changing a local copy of it. You need to pass a pointer instead.
|
# ? Oct 21, 2013 16:24 |
|
That is a very simple explanation for what I thought was gonna be a really complicated problem. Thanks; like I said, I'm really not that great at C.
|
# ? Oct 21, 2013 16:35 |
I've found myself digging into a lot of large projects lately, and have found my current toolset pretty inefficient for exploring a big unknown body of code. I have the function I'm interested in which includes a bunch of objects of a class I'm not familiar with, which have a bunch of member objects I'm also not familiar with, all having their various member functions called. I've pretty much always done my editing in vi and that works great when I know what I'm looking at and which file contains what I need. I've experimented with loading the project up on code::blocks so I can click on something and "go to definition" and that works, but I still suspect there is a better option. Is there any recommended plugins for vi that could help? A better program all together? Delta-Wye fucked around with this message at 17:58 on Oct 21, 2013 |
|
# ? Oct 21, 2013 17:31 |
|
YouCompleteMe provides go-to-declaration/go-to-definition operations but I've found its reliability a bit sporadic. You may have better luck than me.
|
# ? Oct 21, 2013 17:54 |
|
Coca Koala posted:I'm really not that great at C. The best thing to do is add threads. Multithreading is easy and is an excellent thing for beginners to tackle.
|
# ? Oct 21, 2013 20:11 |
|
Coca Koala posted:Mutex stuff This is still going to be wrong on multiprocessors. Nothing guarantees that all the threads see memory accesses in the same order. I don't think there's any portable way to reimplement mutexes. You need fence instructions for whatever your processor you're on or a guarantee that it doesn't need them.
|
# ? Oct 21, 2013 23:50 |
|
Is there a word for binaries that are just linked together libraries and do not contain any of their own symbols?
|
# ? Oct 23, 2013 16:12 |
|
The Little Book of Semaphores. The C chapter starts on p255 with a mutex example, though you'd do well to read Chapters 1-3 first.
|
# ? Oct 23, 2013 16:23 |
|
Dren posted:Is there a word for binaries that are just linked together libraries and do not contain any of their own symbols? ...Isn't "binaries" sufficient? And what do you mean by "own"? What kind of library has no symbols?
|
# ? Oct 23, 2013 16:55 |
|
coffeetable posted:The Little Book of Semaphores. The C chapter starts on p255 with a mutex example, though you'd do well to read Chapters 1-3 first. This looks like a really helpful resource; thanks for bringing my attention to it!
|
# ? Oct 23, 2013 17:09 |
|
Doctor w-rw-rw- posted:...Isn't "binaries" sufficient? And what do you mean by "own"? What kind of library has no symbols? It's a binary that consists solely of linked together shared objects. The real issue is that I am going to have to explain why certain binaries don't show up as having a Stack Canary when checksec.sh is run on them. If a binary doesn't link at least one object file it won't have any symbols that actually got compiled with stack canaries (-fstack-protector-all) and thus will be reported as not having a stack canary on the test. I'd like to get a better understanding of what's really going on so that I can allay the fears of people who run the test but have no clue what it's doing. I think I've found the explanation for the code that does exist in the binary: http://www.delorie.com/gnu/docs/gcc/gccint_149.html
|
# ? Oct 23, 2013 17:25 |
|
The question you meant to ask "Is there a word for object files that contain no executable code?" And even that isn't exactly right, because there's functions that won't have canaries because they don't need them. That script is rather dumb.
|
# ? Oct 23, 2013 17:47 |
|
pseudorandom name posted:The question you meant to ask "Is there a word for object files that contain no executable code?" The binary does contain executable code. It's boilerplate code that gcc sticks in there for running constructors when the program starts. The way I'm thinking I will talk about these files is by saying they "contain nothing but compiler supplied boilerplate code". I totally agree with you about the dumbness of that script.
|
# ? Oct 23, 2013 18:12 |
|
There's plenty of non-boilerplate user-created functions that don't need canaries and won't have them.
|
# ? Oct 23, 2013 18:22 |
|
pseudorandom name posted:There's plenty of non-boilerplate user-created functions that don't need canaries and won't have them. Thanks, I will also include some information about other ways to compile something with -fstack-protector-all and fail the test. edit: actually, I can't seem to find any. Even a trivial object file gets a canary with -fstack-protector-all (when it doesn't with -fstack-protector) C code:
code:
Dren fucked around with this message at 18:43 on Oct 23, 2013 |
# ? Oct 23, 2013 18:37 |
|
Oh, I missed that you're using -fstack-protector-all. That might actually cover everything that isn't compiler generated. You may want to mention something about object files that contain only data, though, just to cover all bases.
|
# ? Oct 23, 2013 18:41 |
|
Coverity tells me that the following code results in an out-of-bounds array read:code:
|
# ? Oct 24, 2013 01:06 |
|
|
# ? Jun 9, 2024 01:49 |
|
I'm having trouble figuring out how to erase from a map. I have a function that takes in a map<string, string> and is supposed to copy certain elements to an empty map of the same type, then erase those elements from the first map:code:
|
# ? Oct 24, 2013 01:16 |