|
Can anyone recommend any good sources of C documentation or tutorials? I'm going through Learn C the Hard Way but many things are left deliberately up to the reader to figure out. I have K&R as well, but something more modern would be nice.
|
# ? Dec 26, 2012 06:05 |
|
|
# ? Jun 8, 2024 06:17 |
|
C Programming: A Modern Approach is really good, and covers C99.
|
# ? Dec 26, 2012 08:31 |
|
Hughlander posted:Go -Weverything or go home. (Clang only.) Note that clang does have a lot of opt-in warnings for people who want to enforce some project-specific convention — like not auto-synthesizing properties in Objective-C — so if you're going to roll with -Weverything, don't feel bad about opting back out of specific things.
|
# ? Dec 27, 2012 00:57 |
|
I view -Weverything as a tool for discovering new warnings you'd like to enable.
|
# ? Dec 27, 2012 03:32 |
|
I'm working with algorithmic audio generation at the bit level (see http://countercomplex.blogspot.com/2011/10/some-deep-analysis-of-one-line-music.html for details). Basically, you take a (bitwise-manipulation heavy) equation with one variable t that gets incremented at the sample rate. The solution gets cast to a char, so you're working with a max of 256. What I'm interested in knowing is when a pattern will repeat—for example, the equation t*(42&t>>10) gives a phrase 65536 samples long, as does t&t>>8. Obviously, the trivial case of t will repeat after 256 samples, while equations like t|t%255|t%257 take much longer. I see two options—somehow analyzing the equation (once) for its periodicity or doing some kind of running comparison (this could even be fuzzy). Any thoughts? The code will eventually be running on an Arduino at 8000hz, so it'd be nice if there were a fast/inexpensive way to do this.
|
# ? Dec 27, 2012 17:10 |
|
The below works fine as long as I keep it in my main but as soon as I try to move it to a function it leads to not being able to bind to the statement further down. The work I try to do: code:
code:
code:
1. I'm not preparing the statement I think I'm preparing when I pass the pointer to the sqllite3_stmt? SQLite is not complaining so far though. 2. If not the above then it's something to do with the statement needing to remember the query text and that goes out of scope when the function exits. This would mean that it working for me is purely coincidental since I'm reusing the same std::string multiple times. InAndOutBrennan fucked around with this message at 12:50 on Dec 30, 2012 |
# ? Dec 30, 2012 12:45 |
As far as I can guess, you aren't correctly passing the sqlite3_stmt out of the function. (You didn't provide the actual code of the function, instead giving a puzzle missing some of the pieces.) Either just return it as a plain return value (and throw an exception on error), or use the same mechanism as the sqlite3_prepare_v2 function by passing in a pointer to a pointer. (Alternatively, a reference to a pointer.) C++ code:
C++ code:
|
|
# ? Dec 30, 2012 13:34 |
|
nielsm posted:...awesome... Well, that did the trick! Thanks! Sorry for not posting all of it but I figured I got the important bits in there. As soon as I think I get those loving pointers down...
|
# ? Dec 30, 2012 13:48 |
woptsufp posted:Well, that did the trick! Thanks! Sorry for not posting all of it but I figured I got the important bits in there. Lesson learned: It can be really hard to know which parts of your code matter, so always provide it verbatim.
|
|
# ? Dec 30, 2012 14:00 |
|
I wanted to get pedantic about returning string literals, like in a case like this:code:
|
# ? Dec 31, 2012 01:47 |
|
String literals are guaranteed to have static storage duration, so it's perfectly safe.
|
# ? Dec 31, 2012 01:51 |
|
Even if it's not legal in the "strictly following the standards" sense, it should always work. If the data is not stored in a global static region somewhere that's mapped into your process (and therefore visible to all code in your process), where else is going to come from that would break when you return the pointer to it from the function? The one case I can think of is if the data is in a shared object that gets unloaded from your process, but that's an exceptionally rare case.
Mr.Radar fucked around with this message at 16:41 on Dec 31, 2012 |
# ? Dec 31, 2012 01:55 |
|
I can't even think of any remotely sane way to store string literals where returning pointers to them wouldn't work. It'd require either copying them to a new location each time they're used, or mapping parts of the executable in and out of the process's address space, both of which would be insane.
|
# ? Dec 31, 2012 05:04 |
|
As Volte mentioned, it will work, they have static storage duration. Just don't try to do that in an inline function and then expect the pointers to compare equally.
|
# ? Dec 31, 2012 05:26 |
|
shrughes posted:Just don't try to do that in an inline function and then expect the pointers to compare equally. What makes you say that? I'm pretty sure the pointers are required to compare equal in any case.
|
# ? Dec 31, 2012 07:57 |
|
Because you'll end up with multiple copies of the string in different compilation units, which may not be merged by the linker.
|
# ? Dec 31, 2012 08:06 |
|
pseudorandom name posted:Because you'll end up with multiple copies of the string in different compilation units, which may not be merged by the linker. I know that that's what's implied by his post, what I'm saying is that I don't think that the claim is correct, and after briefly skimming through the standard I don't see anything that points to it being true. As far as I'm aware, the behavior should be the same regardless of function inlining, much like how any [non-const] function-static variable is the same between translation units even when the function is inline. Whether the function is inline or not shouldn't have any effect. e: To be clear, I agree that it is reasonable to expect the pointers to not compare equal, I'm just not convinced it is standard for an implementation to do so. That Turkey Story fucked around with this message at 09:53 on Dec 31, 2012 |
# ? Dec 31, 2012 09:32 |
|
That Turkey Story posted:e: To be clear, I agree that it is reasonable to expect the pointers to not compare equal, I'm just not convinced it is standard for an implementation to do so. One copy lives in a shared library, one in the executable? Only thing that springs to mind.
|
# ? Dec 31, 2012 09:56 |
|
UraniumAnchor posted:One copy lives in a shared library, one in the executable? The standard doesn't deal with "shared libraries."
|
# ? Dec 31, 2012 10:09 |
|
Plorkyeran posted:I can't even think of any remotely sane way to store string literals where returning pointers to them wouldn't work. It'd require either copying them to a new location each time they're used, or mapping parts of the executable in and out of the process's address space, both of which would be insane. In Windows, call FreeLibrary() and boom, part of the executable is out of the process's address space. A game I used to work on was an engine as the executable and then a client dll and a server dll. Between levels we'd call FreeLibrary() on the server dll to reclaim memory.
|
# ? Dec 31, 2012 15:38 |
|
That Turkey Story posted:I know that that's what's implied by his post, what I'm saying is that I don't think that the claim is correct, and after briefly skimming through the standard I don't see anything that points to it being true. As far as I'm aware, the behavior should be the same regardless of function inlining, much like how any [non-const] function-static variable is the same between translation units even when the function is inline. Whether the function is inline or not shouldn't have any effect. Both C and C++ require the arrays backing string literals to have static storage duration, but they explicitly decline to make guarantees about whether these arrays are distinct objects from each other: C11 6.4.5p7 posted:It is unspecified whether these arrays are distinct provided their elements have the appropriate values. "C++11 [lex.string posted:p12"] I would argue that this does weaken the requirements enough to permit a single string literal to yield distinct objects on different executions. Someone with an axe to grind could raise hell with one committee or the other, though, and they'd probably win a concession for non-inline functions (for each of the committees' highly divergent definitions of inline), but there's zero chance they'd win a broad new language guarantee: implementors would fight it tooth-and-nail. rjmccall fucked around with this message at 01:46 on Jan 1, 2013 |
# ? Jan 1, 2013 01:41 |
|
rjmccall posted:I would argue that this does weaken the requirements enough to permit a single string literal to yield distinct objects on different executions. rjmccall posted:Someone with an axe to grind could raise hell with one committee or the other, though, and they'd probably win a concession for non-inline functions e: This also shouldn't be a difficult thing to implement, unless I'm missing something. It can be done in the same way as function-static variables -- just treat a given string literal as though it had some implementation-defined name based on an index into the set of string literals of that particular function. That Turkey Story fucked around with this message at 10:45 on Jan 1, 2013 |
# ? Jan 1, 2013 08:42 |
|
This is where I come in and say the only reason I was seeing problems was that the printf I was trying to use for my returned string literal printed only one thing, but I had given it two things to print. So it wasn't even an issue of the string literals.
|
# ? Jan 1, 2013 10:30 |
|
That Turkey Story posted:I interpret it as just stating that multiple strings with overlapping data may potentially refer to the same object (as is described in the note). I.E. if a function has a line char const* a = "hello", * b = "hello"; then it is allowed for an implementation to have a be equal to b. I'd think that if it were meant to be interpreted in the broader sense then it would be opening the door for potential ODR violations, wouldn't it? All a function would have to do is refer to the address of the string or one of its elements (such store the address of the first element in a char const*, which is clearly very common). Then again, there is no explicit mention string literals in [basic.def.odr] and they technically don't fall under the types of objects that are touched on (they aren't temporaries, but they also aren't named), so perhaps it would be allowable. Oh, if we're discussing original intent then yes, absolutely, I think they were just trying to allow strings to be coalesced; I don't think they intended to allow different evaluations of the same expression to yield different objects. But there's no way to give this consistent semantics in either language without completely prohibitive costs. In C++, you'd have to create a symbol with weak linkage for every string used in an inline function, just in case its address turns out to matter — and unlike the symbol for the inline function itself, that's generally not optimizable, because inlining usually won't eliminate the need for the string or tell you that its address is irrelevant. It'd actually be worse than that in C: you'd have to either ban string literals outright in inline functions, or you'd have to make a symbol with external linkage for literally every string appearing in a function with external linkage (i.e. most functions), because you don't know when processing a function definition whether or not there might be an inline definition in a different translation unit. Both are totally prohibitive since basically nobody uses string literals in this way. That Turkey Story posted:I also have no idea what the common implementations do here as I've never tested it, but I'd be interested in seeing results in practice. Well, the obvious emission pattern for a string literal is just to generate an anonymous, internal-linkage global array, preferably in some sort of string-literals data section that the linker will unique. That gives you consistent semantics for non-inline functions, ignoring optimization. Inlining could be a problem if you have an AST inliner (†) — except that as far as I know, every professionally-written C/C++ compiler does its own uniquing of strings within a translation unit, so that's still not a problem. So it's really just the cross-translation-unit situations, and if you need those to have consistent semantics, the compiler needs to start with the global symbols. † An AST inliner works as if the AST of the called function were copied into the caller, usually either by literally replacing the call expression with a copy of the callee's body, or by processing the callee's body as if processing statements in the caller. AST inliners have to be careful about things like static local variables which need to be unique despite the inlining. The alternative is to have first lowered the callee's AST to some sort of IR (in which a string literal would just be a reference to a global array) and then copy that IR into the IR for the caller (merely creating a new reference to the same global array and thus preserving semantics).
|
# ? Jan 1, 2013 10:30 |
|
Rocko Bonaparte posted:This is where I come in and say the only reason I was seeing problems was that the printf I was trying to use for my returned string literal printed only one thing, but I had given it two things to print. So it wasn't even an issue of the string literals. Are you not rolling with -Wformat? I thought every compiler had an equivalent to this.
|
# ? Jan 1, 2013 10:31 |
|
rjmccall posted:Are you not rolling with -Wformat? I thought every compiler had an equivalent to this. Apparently not. I went and screwed it up again just to see, and I don't have any warnings in the compiler messages. I'm using Visual Studio 2010. Well, I have more problems here, now related to heap stuff. I am building a 64-bit Windows console test program where I intend to blow through a lot of heap. However, I seem to blow through the heap waaaay too early, so I'm trying to get a sanity check here. I have a class that contains 4 arrays of dynamically-allocated floats. These 4 arrays should have 1024 elements in them. I intend to create 16,800 instances of that class in yet another array. I intend to create two sets of these to compare against each other. Disregarding anything with memory alignment going on, I should be allocating roughly 1024 elements * 4 arrays per element * 4 bytes per float * 16,800 instances * 2 sets of these = 525MB. We can start to talk about the size of the container for these instances but I consider that negligible to the mass of floating-point arrays I'm allocating. I have 16GB of RAM. I'm not running other crazy shenanigans at the same time. Somehow I die around the allocation of the arrays for container index 3577. What gives? I'd love to be able to check how much real RAM I have free but I don't know what's a real call to get that. All I could see online was stuff that would factor in virtual memory, and that is some huge, useless, unchanging number.
|
# ? Jan 6, 2013 06:41 |
|
Could you be overflowing your stack by any chance? You can set the memory limits for the heap and the stack somewhere in the project properties, so give that a try if you want.
|
# ? Jan 6, 2013 07:56 |
|
Rocko Bonaparte posted:Apparently not. I went and screwed it up again just to see, and I don't have any warnings in the compiler messages. I'm using Visual Studio 2010. If you are using a paid version with code analysis, you can use this to validate your string formatting.
|
# ? Jan 6, 2013 18:24 |
|
Captain Cappy posted:Could you be overflowing your stack by any chance? You can set the memory limits for the heap and the stack somewhere in the project properties, so give that a try if you want.
|
# ? Jan 6, 2013 19:32 |
|
Trying to come up with an elegant solution for this. I have a SpriteBatch class, it needs to know about your underlying Vertex structure (and index buffer type) so I thought to just use a template. code:
|
# ? Jan 7, 2013 10:56 |
|
slovach posted:But I thought about what if I don't want to use an index buffer for my rendering? Is there a way to "overload" my functions so if you don't provide T2, it uses another version? Have T2 default to some dummy type and branch accordingly -- you can do this directly by writing partial specializations, or you can do it indirectly with std::conditional.
|
# ? Jan 7, 2013 11:15 |
|
Noice, that did the trick. Thanks.
|
# ? Jan 7, 2013 12:35 |
|
I figured it's good idea to learn how to use unit tests so I picked Boost Test since I had Boost installed. However, when I try to compile any unit tests with C++11 support turned on, I get an error complaining that putenv is undefined, while it compiles just fine when I turn the support off. This is a problem because I'd like to add unit tests to my personal project which is written in C++11. Is there any way to make boost test behave nicely? I'm using MinGW 4.7.2. EDIT: GCC defines __STRICT_ANSI__ when compiling with -std=c++11 or -std=c++0x which disables putenv among other things, so simple #undef __STRICT_ANSI__ fixed this. Valtis fucked around with this message at 17:10 on Jan 10, 2013 |
# ? Jan 10, 2013 11:41 |
|
It's been a long rear end time since I've written C, and so I need some assistance. I'd like to read floating point numbers (separated by whitespace) from a text file while dynamically creating a 2D array (the numbers are a matrix, with each row ending with a '\n'). I need to go for performance, so I figure this would be the fastest method of doing so, instead of reading each line into a buffer with fgets, then running through that line with fscanf(). It was suggested to use mmap to map the file into memory first so I'd get faster I/O, but I'm not entirely sure how to use it, especially with what I want to do. Googling around, I haven't seen very many helpful code examples for my use case. Any C guru's wanna suggest how to start writing this? Thanks!
|
# ? Jan 10, 2013 14:12 |
For a single, linear read of the file I don't think you'll gain anything from mmapping it. The standard buffering provided by OS and stdlib should be sufficient for performance. I'd suggest just writing the naive implementation first and see how it performs. If it's too slow then measure it and figure out what the actual hot spots are.
|
|
# ? Jan 10, 2013 14:17 |
|
Also, writing floating-point values (as text) to a file and reading them back in won't necessarily give you the exact same values. Unless you care about the file being human-readable, you might want to consider writing binary data instead (this is easier and will improve filesize, performance and accuracy).
|
# ? Jan 10, 2013 18:50 |
|
seiken posted:Also, writing floating-point values (as text) to a file and reading them back in won't necessarily give you the exact same values. Unless you care about the file being human-readable, you might want to consider writing binary data instead (this is easier and will improve filesize, performance and accuracy).
|
# ? Jan 10, 2013 19:45 |
|
roomforthetuna posted:Though it can make cross-platform-ness trickier. Binary representation of floating point is an IEEE standard isn't it? Other than maybe endianness.
|
# ? Jan 10, 2013 21:47 |
|
Progressive JPEG posted:Binary representation of floating point is an IEEE standard isn't it? Other than maybe endianness.
|
# ? Jan 10, 2013 21:51 |
|
|
# ? Jun 8, 2024 06:17 |
|
seiken posted:Also, writing floating-point values (as text) to a file and reading them back in won't necessarily give you the exact same values. Unless you care about the file being human-readable, you might want to consider writing binary data instead (this is easier and will improve filesize, performance and accuracy). Actually, the standard specifically states that every floating point number have a character representation that is also convertible back to the original floating point number. This is 9 decimal digits for a float and 17 for a double.
|
# ? Jan 11, 2013 02:59 |