|
csammis posted:Did you look into any of the books recommended in the OP? Accelerated C++ has this right on their preface:
|
# ? Apr 28, 2011 16:32 |
|
|
# ? Apr 29, 2024 06:03 |
|
Does anyone have any ideas about my weird linker problem
|
# ? Apr 28, 2011 19:56 |
|
GrumpyDoctor posted:Does anyone have any ideas about my weird linker problem When you say a symbol from the standard library, you're referring to vector<int>, right? The problem is that vector is a template, so it's not compiled into a library the way other things you get from libraries are, like classes or functions. Templates exist only in .h/.hpp files until something actually defines them with types, at which point the compiler generates code for them. In other words, template vector<T> has no object code, and is ignored by the linker, vector<int> my_vector; on the other hand does generate object code and can be linked. So in a way, there is no linkable symbol for vector in the STL library. It looks like both third party libraries are making use of vector<int> in such a way that they both contain object code for it, and the linker is upset because it doesn't know which version to use. I'm not sure if there's a way of configuring the linker or changing your code to fix the issue, you may want to get in touch with the people who make the libraries and ask them. There are people who post here who have a far better understanding of linker/compiler architecture than me though, so they may be able to help you more...
|
# ? Apr 28, 2011 22:12 |
|
GrumpyDoctor posted:Does anyone have any ideas about my weird linker problem Is this at all similar/appropriate? http://www.pcreview.co.uk/forums/stl-template-symbol-already-defined-errors-t1429969.html
|
# ? Apr 28, 2011 22:22 |
|
That issue in your link has happened to me before, and initially that's what I thought the problem was. However that problem causes linker errors to be generated from the standard run time libraries (MSVC xxxx .lib) and the errors aren't coming from those files.
|
# ? Apr 28, 2011 22:47 |
|
So, symbols from template specializations/instantiations are normally treated as "inline", so that by C++ rules they're given "coalescing" linkage, meaning that multiple symbols with the same name are joined by the static and dynamic linkers so that at runtime there's only one address for that symbol. For some reason that's not triggering here. I know that some compilers have had bugs where they've given explicit instantiations (template class std::vector<int>;) strong linkage, which then causes this kind of link failure; maybe that's it. I don't know nearly enough about the Microsoft linking model, or your build system, to comment further. The fact that it's an instantiation of std::vector doesn't matter; STL implementations generally do not provide any explicit instantiations of std::vector, because (unlike e.g. std::basic_string<char>) there aren't any obvious instantiations that most programs using the STL will need. rjmccall fucked around with this message at 23:29 on Apr 28, 2011 |
# ? Apr 28, 2011 23:27 |
|
rjmccall posted:The fact that it's an instantiation of std::vector doesn't matter; STL implementations generally do not provide any explicit instantiations of std::vector, because (unlike e.g. std::basic_string<char>) there aren't any obvious instantiations that most programs using the STL will need. Not that this has anything to do with the problem at hand, but doesn't the STL specialize vector<bool> to use single bits?
|
# ? Apr 29, 2011 00:57 |
|
The1ManMoshPit posted:Not that this has anything to do with the problem at hand, but doesn't the STL specialize vector<bool> to use single bits? Yes.† Because it's an explicit specialization, though, that code is compiled into every translation unit that needs it, rather than being provided once by the standard library. (†) Right-thinking C++ programmers hate this with every once of their being, though.†† (††) Right-thinking C++ programmers are very hateful people in general.
|
# ? Apr 29, 2011 01:09 |
|
Well the problem apparently goes away if I don't instantiate std::vector<int> in my own code.
|
# ? Apr 29, 2011 01:35 |
|
I am writing a DLL (in Visual Studio) for the first time ever. I have noticed that it seems to be Not Okay to export STL classes from DLLs. I am using std::string, std::vector, and std::map in my code. My question is this: Can I use STL classes at all? For example, can I have a class with non-exported functions or private data members that use these classes? The warning is still thrown, even when I remove all public methods with STL classes as parameters or return values, and I'm not sure exactly what's kosher. Do I have to re-write the map class to use it in a DLL?
|
# ? Apr 29, 2011 03:21 |
It gets messy exporting anything relying on templates from DLLs, as far as I'm aware. Try writing a thin wrapper class that simply has an instance of the appropriate STL class instantiation and has methods that just forward to the STL class' methods. You may even need to wrap that in an abstract interface as well to be completely safe. (So your function signatures would talk about an abstract base class for your actual implementation of the STL wrapper.)
|
|
# ? Apr 29, 2011 03:53 |
|
nielsm posted:It gets messy exporting anything relying on templates from DLLs, as far as I'm aware. Just to clarify, this thin wrapper is entirely for internal use in the DLL, right? I don't need to have any member functions that have STL classes as parameters or return values, and I don't need any publicly accessible member variables that are instances of STL classes. As an additional thing, could you explain why this would solve my problem? I've done pretty much all of my C++ on Linux before this and I'm a bit confused why adding another layer of indirection would automagically fix things.
|
# ? Apr 29, 2011 06:43 |
|
It's not templates per se, but because of allocators and this. Long story short, DLL APIs should look like thiscode:
code:
code:
However, if the third example makes your library considerably more convenient and expressive, use a LIB instead of a DLL and this problem goes away. DLLs are overused anyhow.
|
# ? Apr 29, 2011 12:58 |
Well yes, see if you can't get away with using static libraries. Valid reasons to use dynamic libraries: 1. You need to be able to dynamically add and remove code, potentially supplied by third parties (i.e. plugins). This requires a very well-thought out API design. 2. You have lumps of code that needs to be built with different compilers or are written in different languages, and you can't create meaningful static libraries. This usually requires an API defined in terms of plain C types and functions. Clearly not the case here. 3. You have code that for legacy reasons needs to define symbols that would clash with other symbols at link time with static libraries. Real example: I have done this to have Lua 5.0 and 5.1 in the same process. 4. Software licenses and libraries you don't have the source code for. Either can also force you to move other parts of code into dynamic libraries. One of the original reasons to have dynamic libraries was a potential to save space, but that isn't as much of a concern any longer. I think you'll have a hard case arguing to shave a couple of MB off the final product at the cost of spending weeks or months designing + implementing an API. TL;DR: Consider whether you really need a DLL. If you do, spend the time to carefully design an API based around abstract interfaces and factories.
|
|
# ? Apr 29, 2011 13:58 |
|
When I ask to input the name, if I do first name [space] last name, it skips the prompt for address and the address variable is this weird /u> thing. What's up with that? Also, how can I get it to add to the text file instead of rewriting it every time I run the function? code:
volatile bowels fucked around with this message at 19:08 on Apr 29, 2011 |
# ? Apr 29, 2011 19:01 |
|
scanf by its nature doesn't work with spaces the way you want it to. use gets()/fgets(). use "a" mode to append to a file.
|
# ? Apr 29, 2011 19:39 |
|
If you use gets you can run into buffer overflow problems. fgets(student.name, 30, stdin) will stop it writing more than 29 input characters and overwriting the address, gpa or even worse, possibly the return address of your function, given you've got it on your stack. EDIT:fgets doesn't let you know how much was actually read without inspection and you can't have it read an arbitrary length string though. If you don't mind using non-standard extensions, glibc has getline and %as which can allocate memory for it. code:
code:
Edison was a dick fucked around with this message at 20:44 on Apr 29, 2011 |
# ? Apr 29, 2011 20:04 |
|
nielsm posted:Well yes, see if you can't get away with using static libraries. What about developing a component for a larger piece of software that you want to be able to update without rebuilding the consuming application (maybe it's not yours)?
|
# ? Apr 29, 2011 21:17 |
GrumpyDoctor posted:What about developing a component for a larger piece of software that you want to be able to update without rebuilding the consuming application (maybe it's not yours)? I'd say that usually falls under the first, something plugin-like.
|
|
# ? Apr 29, 2011 21:35 |
|
I'm working on an assignment for class where the professor gave us a majority of the code required and asked us to make some modifications to code to handle scheduling. But I'm noticing that the (pseudo-)random number code that was provided doesn't seem to actually be generating random numbers. The program can take a command line parameter to set the seed manually, or if one isn't provided uses the current time. The code changes that I made had nothing to do with the RNG (as the template code also shows seed-independent sequencing), and fixing the RNG is not mentioned anywhere in the assignment. I've sent an email to the TA but not expecting a response soon, and was hoping if anyone else could describe why it might be doing this.code:
EDIT: This isn't me saying "I don't think its random enough," its that regardless of seed the exact same numbers are generated each time. Ixiggle fucked around with this message at 21:12 on Apr 30, 2011 |
# ? Apr 30, 2011 21:08 |
|
Does the provided code ever check argc anywhere, or does it just blindly assume that reading argv[1] will always work?
|
# ? Apr 30, 2011 21:14 |
|
pseudorandom name posted:Does the provided code ever check argc anywhere, or does it just blindly assume that reading argv[1] will always work? Yep, it does. The code that the rng seeding is in is part of a initialization call made by main. Main checks argc for the correct number of parameters, and if not prints a debug message. I also cut out some comments/debug messages from the above code, one of them returning the value being used for the seed that confirms that its reading parameters in correctly. I've checked that as well and it seems like its being read properly.
|
# ? Apr 30, 2011 21:22 |
|
Try putting printf("%d => %d\n",seed,rand()); right after srand(seed). That'll tell you if the problem is with the RNG or the seed or your initialization function being called twice or what.
|
# ? Apr 30, 2011 22:20 |
|
roomforthetuna posted:Try putting printf("%d => %d\n",seed,rand()); right after srand(seed). That'll tell you if the problem is with the RNG or the seed or your initialization function being called twice or what. Okay, tried that out and it seems to be functioning like I would expect it to, giving different numbers for new seeds and the same on consistent seeds. Still behaving as it did before outside of the init() function. I don't know C very well, but could the program having two threads be the cause of it?
|
# ? Apr 30, 2011 22:39 |
Van Ishikawa posted:Okay, tried that out and it seems to be functioning like I would expect it to, giving different numbers for new seeds and the same on consistent seeds. Still behaving as it did before outside of the init() function. I don't know C very well, but could the program having two threads be the cause of it? Yeah, the runtime library might very well have thread-local random generator seeds. If you want fully portable behaviour you're probably better off writing a random generator of your own. (It doesn't need to take more than 10 lines of code for a simple linear congruential one.)
|
|
# ? Apr 30, 2011 23:11 |
|
nielsm posted:Yeah, the runtime library might very well have thread-local random generator seeds. I heard back from the TA and that was his answer as well (runtime libraries). Actual evaluation of the code is done in a different environment than the one I'm developing in. I just tried running it on the school server we deliver the final code to and it was generating random numbers as normal. Thanks to everyone who helped!
|
# ? Apr 30, 2011 23:54 |
|
int main () { int nn = 5,k; printf("Here is a Table of %d Numbers\n",nn); int *ntable = (int *) calloc (nn,sizeof(int)); Does the bolded line just initialize the pointer variable ntable to have size of nn? is the only reason to initialize it like that to prevent memory overflows?
|
# ? May 3, 2011 01:30 |
|
volatile bowels posted:int main () { Not quite. The function allocates enough memory for nn ints, then returns a pointer to the beginning of that block of memory. so, your code snippet there initializes a pointer-to-int to point to the beginning of a block of memory allocated to hold nn ints. please use code tags. Also what does nn=5,k mean?
|
# ? May 3, 2011 01:46 |
|
Not exactly a horror, but it surprised me thatcode:
Edit: Oh look, this isn't the coding horrors thread. shrughes fucked around with this message at 02:21 on May 3, 2011 |
# ? May 3, 2011 02:08 |
|
TasteMyHouse posted:Also what does nn=5,k mean? If I rewrote it like so, would it help? code:
|
# ? May 3, 2011 02:32 |
|
Jabor posted:If I rewrote it like so, would it help? no, I know that that is valid C/C++ and what it means. I just don't understand what function he thought it was fulfilling as part of his example.
|
# ? May 3, 2011 02:53 |
|
TasteMyHouse posted:no, I know that that is valid C/C++ and what it means. I just don't understand what function he thought it was fulfilling as part of his example. It looks to me like "I'm not entirely sure what is/isn't related, I'll copy-paste the whole code up to that point so I don't leave out any crucial detail". Unless the question was rhetorical?
|
# ? May 3, 2011 06:19 |
|
nielsm posted:Yeah, the runtime library might very well have thread-local random generator seeds. By the way, MSVC's random number generator seeds are in thread-local storage; just an FYI.
|
# ? May 4, 2011 00:02 |
|
Newbie question. code:
It keeps giving these errors code:
|
# ? May 4, 2011 05:01 |
|
#include directives expect paths in quotes or angle brackets.
|
# ? May 4, 2011 05:08 |
|
pseudorandom name posted:#include directives expect paths in quotes or angle brackets. Wow thanks. I'm staring at it in the book completely ignoring the quotes about to pull my hair out. This is going to be a long journey.
|
# ? May 4, 2011 05:19 |
|
I'm attempting to write a simple bmp writer in plain C, just to get the hang of it again. I'm attempting to compile (this is in PellesC ) and i keep getting this error when I have a backslash for hex escape. code:
code:
On another note does anyone know of a good way to read structs byte by byte? At the moment I am creating a char* and pointing it to the address of the int I want read byte by byte. I feel this is incredibly dangerous. What's the right way?
|
# ? May 4, 2011 18:17 |
|
You need to wrap single chars in '' so '\x424d'. Assuming that entire thing is supposed to be a single char. If it's supposed to be a string, double quotes. For the second one you might have to explain to me why you want to read a struct bytewise in the first place, not having to do that is generally why structs exist in the first place.
|
# ? May 4, 2011 18:31 |
|
I thought you were trying to do chars too at first, but looking again you're adding things to sizes, in which case the notation for hex numbers is not \xff but 0xff. And the 'proper' way to do a struct as both elements and bytes is with a union, eg. code:
code:
|
# ? May 4, 2011 18:39 |
|
|
# ? Apr 29, 2024 06:03 |
|
roomforthetuna posted:I thought you were trying to do chars too at first, but looking again you're adding things to sizes, in which case the notation for hex numbers is not \xff but 0xff. The values are ints and shorts, I didn't realise that you needed a different notation. quote:And the 'proper' way to do a struct as both elements and bytes is with a union, eg. Ahh I didn't think unions worked like that. Clearly I need to read up on them. Thanks for this it gives me something to think on. quote:
This is also very helpful, now I can see how to do that. UraniumAnchor posted:For the second one you might have to explain to me why you want to read a struct bytewise in the first place, not having to do that is generally why structs exist in the first place. Well this is where I figure I am doing something wrong. I've created structs for the headers (dib and bmp), and functions to fill those structs with relevant data. However the data in them is in ints and shorts generally. I'm unclear as how I am supposed to write an int into a binary file as all I can find is fputs/c or fprintf. Generally I am having problems structuring a C program. I went through university on a compsci course and passed but I actually have no idea how to structure something in a non-OO language . Part of the problem I have with the course there. I recently decided to go through the BRogue source code to see how it was structured, and I have started but still. It is tricky. Many thanks for this regardless
|
# ? May 4, 2011 19:22 |