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
VikingofRock
Aug 24, 2008




roomforthetuna posted:

This would be a good time to learn some debugging techniques, I'd say.

This is something I've been meaning to do for a while. Where's a good place to start?

Adbot
ADBOT LOVES YOU

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!

VikingofRock posted:

This is something I've been meaning to do for a while. Where's a good place to start?
What's your development environment?
gdb is the Linux command-line debugger, it's not much fun but it just about works. It's often easier to use the old-school option than it is to use gdb.
Visual Studio makes it super easy, you click next to the code you want to debug and a red dot appears, when the code gets there it stops, then there are keystrokes to move around in code, all of which are explained in the Debug menu, and it automatically shows the values that are in the nearby variables you're likely to care about.
There's a Linux IDE that does that too but I don't know what it is (and there's also Visual Studio for Linux now).
Or you can do it old-school, which tends to be necessary for multi-threaded things or client-server things, which is to just put lines in your code that write the stuff you care about at the times you care about it to stdout or stderr. Or if you just want to see what the code path is, I often just do something like
code:
printf("a\n");
[line of code]
printf("b\n"); 
[line of code]
Then you can run it and look at the sequence of abcdcdcdcdef or whatever and see where something unexpected happened (I expected 5 of d, or why is there no e, or whatever)

I've never seen anything that tries to *teach* debugging techniques. It's a really weird gap in CS curricula, interview tests, etc.

roomforthetuna fucked around with this message at 20:07 on May 2, 2015

hooah
Feb 6, 2006
WTF?
The Linux IDE you're thinking about is likely Netbeans, but its debugging isn't nearly as nice as Visual Studio, especially for things like containers; vectors are a huge pain in the rear end to debug in Netbeans.

Joda
Apr 24, 2010

When I'm off, I just like to really let go and have fun, y'know?

Fun Shoe
CLion's debugging (which uses gdb) works almost as well as Visual Studio's. You can make break points, investigate all symbols in scope and you can even hover your mouse over symbols in your code to see their values when the program has stopped at a break point. (it also adds comments in your code showing the current break point value of symbols at their declarations.) I'm not sure what your options to get CLion is at the moment unless you're a student, but at the very least there's a 30 day trial period. I'm pretty sure you can get it for free for non-commercial applications though.

This is debugging with CLion in action:



Honestly I'm liking it more the more I work with it. It's super easy to set up too, as long as you make sure your gdb version corresponds to your gcc version (this should be automatic if you just use your standard repos versions.)

One thing I'm missing is some automatation for investigating STL containers like vectors, since browsing through iterators to find the actual values can be a pain in the rear end.

E: You can actually get full-blown VS + MSVC for Linux now? I thought I heard something like that, but all I could find was Visual Studio Code, which seemed like it was geared more towards net developers.

Joda fucked around with this message at 20:56 on May 2, 2015

Star War Sex Parrot
Oct 2, 2003

roomforthetuna posted:

I've never seen anything that tries to *teach* debugging techniques. It's a really weird gap in CS curricula, interview tests, etc.
Are you talking an entire course devoted to debugging techniques? I've encountered several programming courses throughout my degree that taught different methods depending on the language and IDE: break points, copious printing to the console, stepping into/through code, Google Test for unit testing, dynamic analysis with Valgrind and AddressSanitizer, as well as entire courses devoted to software engineering best practices (especially testing). I wouldn't say there was a huge gap in my CS curricula. My suspicion is that it depends on the school and the degree.

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!

Star War Sex Parrot posted:

Are you talking an entire course devoted to debugging techniques? I've encountered several programming courses throughout my degree that taught different methods depending on the language and IDE: break points, copious printing to the console, stepping into/through code, Google Test for unit testing, dynamic analysis with Valgrind and AddressSanitizer, as well as entire courses devoted to software engineering best practices (especially testing). I wouldn't say there was a huge gap in my CS curricula. My suspicion is that it depends on the school and the degree.
I'm sure it depends on the place. It seems like yours is the exceptional case, because internet questions about why poo poo's not working are clearly coming from people who haven't been taught any way to debug, but I suppose that might just be selection bias, maybe 95% of places teach that stuff and you just don't see any questions from those people because they can all solve their own "why doesn't this work" problems.

I didn't mean an entire course - unless you get into unit testing frameworks and stuff there isn't really that much you need to learn. But every "programming 101" should have at least a small mention of how you go about figuring out why stuff doesn't work (other than the ridiculous "dry run in your head" model from the days of punch cards), and a lot of them don't. I haven't seen it in a book or online tutorial either, other than "how to use gdb" tutorials which are a layer too late to be helpful to beginner programmers who don't know that there is such a thing or when to use it.

Star War Sex Parrot
Oct 2, 2003

roomforthetuna posted:

I'm sure it depends on the place. It seems like yours is the exceptional case, because internet questions about why poo poo's not working are clearly coming from people who haven't been taught any way to debug, but I suppose that might just be selection bias, maybe 95% of places teach that stuff and you just don't see any questions from those people because they can all solve their own "why doesn't this work" problems.
Yep, I'm leaning toward selection bias. Speaking as a programming tutor for my university (helping students who are going through the classes I described earlier) it's more that the people who are asking for help generally just aren't strong programmers or debuggers yet. It takes time. It could come across as not knowing about debugging tools at all, but instead I think that the students aren't sure how to apply them if the don't understand the problem they're trying to solve in the first place. I also have to remind myself that the students asking for help typically aren't hobbyist programmers, so they're probably being exposed to these concepts for the first time.

America Inc.
Nov 22, 2013

I plan to live forever, of course, but barring that I'd settle for a couple thousand years. Even 500 would be pretty nice.

roomforthetuna posted:

This would be a good time to learn some debugging techniques, I'd say.
Yes. In my programming classes I haven't yet found that I need to do rigorous debugging because I'm usually ahead of the material and I expect to finish an assignment pretty easily (where I can sort out problems usually through stepping through the logic) and this time I encountered some new material and got frustrated. I did want to use STL strings because it would reduce redundancy in the code and save space, but on write operations I would get extra garbage values in between my legitimate data, probably because I wasn't doing it right.
That being said, a debugging class would be a lot of fun.

America Inc. fucked around with this message at 22:04 on May 2, 2015

VikingofRock
Aug 24, 2008




roomforthetuna posted:

What's your development environment?
gdb is the Linux command-line debugger, it's not much fun but it just about works. It's often easier to use the old-school option than it is to use gdb.
Visual Studio makes it super easy, you click next to the code you want to debug and a red dot appears, when the code gets there it stops, then there are keystrokes to move around in code, all of which are explained in the Debug menu, and it automatically shows the values that are in the nearby variables you're likely to care about.
There's a Linux IDE that does that too but I don't know what it is (and there's also Visual Studio for Linux now).
Or you can do it old-school, which tends to be necessary for multi-threaded things or client-server things, which is to just put lines in your code that write the stuff you care about at the times you care about it to stdout or stderr. Or if you just want to see what the code path is, I often just do something like
code:

printf("a\n");
[line of code]
printf("b\n"); 
[line of code]
Then you can run it and look at the sequence of abcdcdcdcdef or whatever and see where something unexpected happened (I expected 5 of d, or why is there no e, or whatever)

I've never seen anything that tries to *teach* debugging techniques. It's a really weird gap in CS curricula, interview tests, etc.

Mostly I just code in vim, and use the "print strings in places" method of debugging. I was wondering if there were any good gdb/valgrind learning resources out there.

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

roomforthetuna posted:

gdb is the Linux command-line debugger, it's not much fun but it just about works. It's often easier to use the old-school option than it is to use gdb.

There's a GUI shell for gdb called "ddd" which is a bit easier to use.
http://www.gnu.org/software/ddd/

Edison was a dick
Apr 3, 2010

direct current :roboluv: only

Zopotantor posted:

There's a GUI shell for gdb called "ddd" which is a bit easier to use.
http://www.gnu.org/software/ddd/

What's remarkable about ddd is how well it has stood the test of time, given it operates by parsing the output of gdb, rather than having using a proper API. This may be because the API did not exist when it was first written and it works well enough (barring the occasional breakage when the output of gdb changes format) that nobody has invested time in fixing it.

Tetraptous
Nov 11, 2004

Dynamic instability during transition.

VikingofRock posted:

Mostly I just code in vim, and use the "print strings in places" method of debugging. I was wondering if there were any good gdb/valgrind learning resources out there.

Valgrind is pretty straight-forward. Compile your program with debug symbols (-g) and then just run valgrind my_program my_programs_args

The trick is learning how to interpret the output; just like compiler error messages, start at the top and fix one problem at a time. Once you get comfortable with valgrind, you can start looking at all of the extra options and tools beyond memcheck (which verify thread synchronization and can profile your program, among other things.) I really don't think you need anything beyond the valgrind man page to get going.

gdb is a little trickier--it can do a lot and more advanced functionality is not always obvious. Since you're a vim user, I'd look towards one of the projects that integrates gdb with the editor. I use emacs, which has good gdb support built in, and I've been told vim can be configured to work similarly. That might help you do basic things like set breakpoints, step through code, and examine variables using an interface you already know. More recent versions of gdb support nifty things like reverse debugging, which allows you to rewind the execution of your program from a given point.

There's also an interface between valgrind and gdb, which I've never used, but I'm assuming you didn't mean that.

Paniolo
Oct 9, 2007

Heads will roll.

In game development it's not uncommon to design data structures this way. It's an optimization for loading times and enables some neat features like saving and loading game state without requiring any complex serialization or fixup.

ExcessBLarg!
Sep 1, 2001

Paniolo posted:

In game development it's not uncommon to design data structures this way.
I appreciate the convenience of "blatting struct to file" as a means of data serialization, albeit one with serious limitations and portability concerns. However I think it's a bit dubious, without motivation, to design a primary data structure around being convenient to serialize. There's better general approaches, especially in C++.

Xerophyte
Mar 17, 2008

This space intentionally left blank

ExcessBLarg! posted:

I appreciate the convenience of "blatting struct to file" as a means of data serialization, albeit one with serious limitations and portability concerns. However I think it's a bit dubious, without motivation, to design a primary data structure around being convenient to serialize. There's better general approaches, especially in C++.
Sometimes fast serialization is a very important concern, and not just for video game state that you wish to transmit over the internet. It's why two of the larger current C++ serialization platforms (specifically FlatBuffers and Cap'n Proto) are based specifically on the in-memory representation being identical to the serialized representation. It lets you do things like zero-copy IPC, which can be quite handy if what you're inter-process-communicating is something like a 10 GB 3D model that you want to send from your modeling application to your rendering process.

Sure, you shouldn't be reinventing the wheel in a professional environment but sometimes having trivial serialization is worth the associated headaches.

pseudorandom name
May 6, 2007

Clearly you should be serializing to JSON in order to get closer to the bare metal.

syncathetic
Oct 21, 2010
Why doesn't C++ support identifiers as template parameters? Ignoring the issue of syntax, are there any technical reasons that hasn't ever been implemented? To explain why I think this would be useful, I would like to be able to write a template function that returns the value of member of an object or some default value if the object doesn't have such member. Currently this is possible if you create one function for each member name you want to check, but it would be cleaner to have just one function that the member name is passed as a template parameter.

nielsm
Jun 1, 2009



You should be able to make a functor to do that.

Not sure if the syntax is valid, but:
C++ code:
template<typename Ct, typename Mt>
class member_fetcher {
  Mt Ct::*member;
public:
  member_fetcher(Mt Ct::*member) : member(member) { }
  const Mt operator() (Ct const &obj) { return Ct.*member; }
  Mt operator() (Ct &obj) { return Ct.*member; }
};

struct Foo { int x; };

auto x_fetcher = member_fetcher<Foo, int>(&Foo::x);

int main() {
  Foo a, b;
  a.x = 1;
  b.x = 2;
  printf("%d %d", x_fetcher(a), x_fetcher(b));
}

Deus Rex
Mar 5, 2005

C++ code:
#include <iostream>
#include <type_traits>

struct HasBar {
    int bar;
};

struct HasBaz {
    int baz;
};

template <typename T>
auto foo_impl(const T &x, int) -> decltype(T::bar)
{
    return x.bar;
}

template <typename T>
auto foo_impl(const T &x, long) -> int // written in this style to compare w/ above
{
    return 1;
}

template <typename T>
auto foo(const T &x) -> decltype(foo_impl(x, 0))
{
    return foo_impl(x, 0);
}

int main()
{
    auto hr = HasBar { 10000 };
    auto hz = HasBaz { 1 };
    std::cout << foo(hr) << std::endl;
    std::cout << foo(hz) << std::endl;
}
The trick is that we define implementation functions with dummy parameters of different types to avoid violating the one definition rule. Then foo instantiates the foo_impl template with a 0 literal as the argument, which "prefers" to be an int, so if the first template (the one with an int dummy parameter) can be substituted with T (i.e. T has a member bar), then that template will be chosen.

There is surely an easier way to do this with stuff like std::enable_if, but I don't know.

Deus Rex fucked around with this message at 11:02 on May 4, 2015

Diametunim
Oct 26, 2010

quote:

e: I'm not sure what the rule on double posting is so I'll just edit this post instead. I finished my HashTable assignment but I'm having trouble with a few of the entries and I'm not quite sure why the other ~40 or so entries work just fine. I'd also like some pointers on how I could optimize / clean my code (StrTab.cpp) up if anyone has any. Here's a gist of my assignment so I don't clutter the thread anymore.

Hate to quote myself but anyone have any advice? Due at 5 today just looking for general advice to clean my code up.

nielsm
Jun 1, 2009



Diametunim posted:

Hate to quote myself but anyone have any advice? Due at 5 today just looking for general advice to clean my code up.

I was writing a comment on how your memory management of the StrTab::stNode objects is really messy with double pointers, but then I noticed you are doing the buckets a different way than I thought.
The basic structure I've learned for hash tables is to not do straight linked lists with "free objects" hanging on, but instead keep every item in the same single table, and then just have indices to items in the table hanging around.
The kind of array of pointers you're doing is sort of messy, memory-wise.

For your bug with items not working, notice that you have 13 items that don't work. Your bucket count is 13. Most likely, you're either skipping the first or the last item in each bucket.


Also, double posting is fine when you're actually writing something new you want attention on, and it's been a while since your last post. Based on the edit time given, it was almost two days between your original post and the edit. Of course nobody's going to notice that change.

nielsm fucked around with this message at 19:28 on May 4, 2015

Sex Bumbo
Aug 14, 2004
Idk if I pasted this in wrong but you're not initializing the links in your linked list to NULL so I get access violations.

code:
		stNode * newNode = new stNode;
		current->link = newNode;
		newNode->key = key;
		newNode->value = value;
Also you're returning std::strings in your get function which is going to do an allocation every time you call it. Which is different from, say, the stl unordered_map which returns references.

Your linked list strategy is to add a dummy link at the beginning which is incorrect and it doesn't examine the last item.

code:
StrTab::stNode* StrTab::findNode(int bucket, const string& key) const
{
	stNode * cursor = buckets[bucket];
 
	while(cursor->link != NULL)
If you test if cursor is null instead of its link it works.

Sex Bumbo fucked around with this message at 20:11 on May 4, 2015

Diametunim
Oct 26, 2010

nielsm posted:

I was writing a comment on how your memory management of the StrTab::stNode objects is really messy with double pointers, but then I noticed you are doing the buckets a different way than I thought.
The basic structure I've learned for hash tables is to not do straight linked lists with "free objects" hanging on, but instead keep every item in the same single table, and then just have indices to items in the table hanging around.
The kind of array of pointers you're doing is sort of messy, memory-wise.

For your bug with items not working, notice that you have 13 items that don't work. Your bucket count is 13. Most likely, you're either skipping the first or the last item in each bucket.


Also, double posting is fine when you're actually writing something new you want attention on, and it's been a while since your last post. Based on the edit time given, it was almost two days between your original post and the edit. Of course nobody's going to notice that change.


Sex Bumbo posted:

Idk if I pasted this in wrong but you're not initializing the links in your linked list to NULL so I get access violations.

CODE

Also you're returning std::strings in your get function which is going to do an allocation every time you call it. Which is different from, say, the stl unordered_map which returns references.

Your linked list strategy is to add a dummy link at the beginning which is incorrect and it doesn't examine the last item.

CODE

If you test if cursor is null instead of its link it works.

Thank you both for the help, got everything sorted out!

MrBadidea
Apr 1, 2009

I want the poo poo out of this for Visual Studio. How many limbs is this going to cost me???

Slash
Apr 7, 2011

MrBadidea posted:

I want the poo poo out of this for Visual Studio. How many limbs is this going to cost me???

Do you mean the mouse over tooltip variable values? It does that already, doesn't work so well for stl types though.

MrBadidea
Apr 1, 2009

StorrowS posted:

Do you mean the mouse over tooltip variable values? It does that already, doesn't work so well for stl types though.

No, the inline variable view; the not-quite-a-comment poo poo appended to a bunch of the lines in that screenshot. It makes way more sense to me than the watch window, and it kinda sits better with how I headspace code I'm working on.

Hughlander
May 11, 2005

MrBadidea posted:

No, the inline variable view; the not-quite-a-comment poo poo appended to a bunch of the lines in that screenshot. It makes way more sense to me than the watch window, and it kinda sits better with how I headspace code I'm working on.

CLion is available for windows now, and I imagine if it allows it ReSharper C++ will have it at some point.

Slash
Apr 7, 2011

MrBadidea posted:

No, the inline variable view; the not-quite-a-comment poo poo appended to a bunch of the lines in that screenshot. It makes way more sense to me than the watch window, and it kinda sits better with how I headspace code I'm working on.

I see what you mean. Yes that would be very handy.

High Protein
Jul 12, 2009

MrBadidea posted:

I want the poo poo out of this for Visual Studio. How many limbs is this going to cost me???

When you inspect a variable you can click the little pin icon for a similar effect.

Joda
Apr 24, 2010

When I'm off, I just like to really let go and have fun, y'know?

Fun Shoe

MrBadidea posted:

I want the poo poo out of this for Visual Studio. How many limbs is this going to cost me???

An individual license is €99 (I imagine it's the same in USD.) Free for educational/open source purposes. To my knowledge, though, the Windows version requires GCC (through MinGW or Cygwin) and won't work with MSVC.

Le0
Mar 18, 2009

Rotten investigator!
I'd like some help on how to do something, I'm using Qt if that makes a difference.

I have an SQL record object (containing all the fields of a specific table) that I pass to a class that creates all the labels/edits needed to fill the values and I'd like for it to update the sql record with the values entered by the user and return it back to me.
I can create all the fields with their name and types without problem but how can I do it easily so that when the user modify the edit values it automatically updates the content of my SQL record object so that I can return it updated at the end?

Eeyo
Aug 29, 2004

I have a LLDB-related question. I've solved the issue, but I'm curious as to why it happens and maybe knowing about this may help someone else.

I've got a program where I send it an SQL query to run in it's command line arguments. I've been terminating the queries with semicolons when I pass it to the program, but I have to do \; since otherwise bash interprets it as 2 complete commands.

code:
./my_prog 5 10 'SELECT puppies, kittens FROM animals WHERE name="max"\;' 50 100
I had some dumb problem with the program so I ran it through LLDB and I set the arguments.

code:
(lldb) settings set -- target.run-args  "5" "10" 'SELECT puppies, kittens FROM animals WHERE name="max";' "50" "100"
(lldb) settings show target.run-args
target.run-args (array of strings) =
  [0]: "5"
  [1]: "10"
  [2]: "SELECT puppies, kittens FROM animals WHERE name="max";"
  [3]: "50"
  [4]: "100"
So it appears that LLDB thinks it has 4 arguments and they all look pretty fine to me. But when I break in main and print argc and argv, I get:

code:
(lldb) print argc
(int) $0 = 4
(lldb) print argv[3]
(const char *) $1 = 0x00007fff5fbff828 "SELECT puppies, kittens FROM animals WHERE name=\"max\""
(lldb) print argv[4]
(const char *) $2 = 0x0000000000000000
LLDB seems to have lost 2 of my arguments somehow. This works fine when I escape the semicolon when I set the arguments. What's happening here? Why does LLDB not like the semicolon at all? Does it pass the arguments through bash, or does it do some of its own interpreting so that the semicolon breaks it?

pseudorandom name
May 6, 2007

I don't know the details of what lldb is doing (it isn't passing the command to bash fwiw, it has to exec the program directly for debugging), but bash shouldn't be interpreting the semicolon in the single quotes in the first place.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Eeyo posted:

LLDB seems to have lost 2 of my arguments somehow. This works fine when I escape the semicolon when I set the arguments. What's happening here? Why does LLDB not like the semicolon at all? Does it pass the arguments through bash, or does it do some of its own interpreting so that the semicolon breaks it?

It does its own interpreting and apparently doesn't honor string literals correctly.

VikingofRock
Aug 24, 2008




I did a cool C++ thing: FizzBuzz in Template Meta Programming

C++ code:
#include <stdio.h>

// struct representing a string. This is the basis of everything.
template <char... Cs>
struct string {
    constexpr static char value[] = {Cs..., '\0'};
};

template <char... Cs>
constexpr char string<Cs...>::value[];

// Use this to append a character to a string.
template <typename S, char C>
struct string_append;

template <char... Cs, char C>
struct string_append<string<Cs...>, C> {
    using result = string<Cs..., C>;
};

// Use this to concatenate two strings
template <typename S1, typename S2>
struct string_concat;

template <char... Cs1, char... Cs2>
struct string_concat<string<Cs1...>, string<Cs2...>>{
    using result = string<Cs1..., Cs2...>;
};

// This is a helper struct for itoa.
// 'B' is whether the number is less than 10
// 'N' is the number
template <bool B, size_t N>
struct itoa_helper;

/* recursive case */
template <bool B, size_t N>
struct itoa_helper {
    using result = typename string_append<
            typename itoa_helper<N/10<10, N/10>::result,
            '0' + N%10
        >::result;
};

/* base case */
template <size_t N>
struct itoa_helper<true, N> {
    using result = string<'0' + N>;
};

// Use this to convert a size_t to a string
template <size_t N>
struct itoa {
    using result = typename itoa_helper<N<10, N>::result;
};

// Use this to either get the string "Fizz" (if 'B' is true), or ""
template <bool B>
struct Fizz {
    using result = string<>;
};

template<>
struct Fizz<true> {
    using result = string<'F', 'i', 'z', 'z'>;
};

// Use this to either get the string "Buzz" (if 'B' is true), or ""
template <bool B>
struct Buzz {
    using result = string<>;
};

template<>
struct Buzz<true> {
    using result = string<'B', 'u', 'z', 'z'>;
};

// Use this to ready a number for printing.
// 'N' is the number
// 'S' is the string produced by (
//     string_concat<typename Fizz<N%3==0>::result,
//                   typename Buzz<N%5==0>::result>::result
//     )
template <size_t N, typename S>
struct ready;

template <size_t N, char C, char... Cs>
struct ready<N, string<C, Cs...>>{
    using result = string<C, Cs...>;
};

template <size_t N>
struct ready<N, string<>> {
    using result = typename itoa<N>::result;
};

// Use this to get the FizzBuzz result for N
template <size_t N>
struct FizzBuzz{
    using result = typename ready<
        N,
        typename string_concat<typename Fizz<N%3==0>::result,
                      typename Buzz<N%5==0>::result
        >::result
    >::result;
};

// Helper struct for FizzBuzzPrinter
// 'N' is the current number
// 'Remaining' is how many numbers we have left
/* recursive case */
template <size_t N, size_t Remaining>
struct FizzBuzzPrinter_helper{
    using result = typename string_concat<
        typename string_concat<
            typename FizzBuzz<N>::result,
            string<'\n'>
        >::result,
        typename FizzBuzzPrinter_helper<N+1, Remaining-1>::result
    >::result;
};

/* base case */
template <size_t N>
struct FizzBuzzPrinter_helper<N,0>{
    using result = typename FizzBuzz<N>::result;
};

// Use this to print out the FizzBuzz results from 1 to N
template <size_t N>
struct FizzBuzzPrinter {
    using result = typename FizzBuzzPrinter_helper<1, N-1>::result;
};

int main() {
    printf("%s\n", FizzBuzzPrinter<100>::result::value);
}
I had never dug this far into TMP before, and it was really fun. My goal was to get the "1\n2\nFizz\n4\nBuzz\n..." result hard-coded into the assembly, and when compiled with clang++ -O3 -S -std=c++11 it looks like I succeeded. If anyone has any feedback on this I'd be happy to hear it.

VikingofRock fucked around with this message at 07:21 on May 12, 2015

jiffypop45
Dec 30, 2011

I have an assignment in which I am to use RTTI to first output a set of objects that share the same superclass to a file, then read that data back in and determine what type of object they are (I don't actually know how feasible this even is, the prof said he has never done it before).

However just trying to output object data to the console (it would be an easy transition to a write this to a file afterward) I am having difficulty getting any of the methods in the typeinfo class to do anything useful for me.

I have a class Vehicle which has subclasses TruckVehicle, MotorcycleVehicle, and TrailerVehicle which has a subclass of TravelTrailerVehicle itself.

I created an array of vehicles as below:

array<Vehicle*,5> v;
v[0] = new Vehicle(params)
v[1] = new TruckVehicle (params)
v[2] = new MotorcycleVehicle(params)
v[3] = new TrailerVehicle(params)
v[4] = new TravelTrailerVehicle (params)

Now what I would like to do is iterate through this array and use RTTI to determine the data type, then downcast to the appropriate subclass so that the correct subclass display method is called (I have overwritten the cout operator in each subclass).

Something like this is what I was hoping would work but it's too simple.

for(int x=0;x <(int)v.size;x++)
{
Vehicle temp = *v[x];
cout<<dynamic_cast<typeid(temp)>(temp);
}

Anyone have any ideas on this? Gotta love a prof who assigns something he isn't even sure if it's possible to do.

nielsm
Jun 1, 2009



C++ is not dynamic in that way. There isn't a good way to create objects of an "unknown type", you need to know about all types that could be created in one way or another.

What you might be able to do, which will probably only work inside a single compiler + standard library version, is have each class be registered in some way.
The registration must include the std::type_info for the class (which importantly has the name member) and the sizeof the actual class instance.

You could then dump the name from the type_info, the sizeof the instance, and a plain dump of the actual instance memory, to a file.
To read it back you would read the name and the size, search for the name in the new process' registration table, and check that the size matches. Then allocate a new chunk of memory of the size and read the dumped data into that. You may then need to fix up the vtable pointer in the object to bring it back to life, and then you can cast the block of memory to a pointer of the base type and play with it.

That is if you really must use RTTI.


What is probably more common for serialization is building on the factory pattern and let each class have a member function that dumps its data into a stream, then have registered another function/something that rebuilds an instance of the object from a stream.

KICK BAMA KICK
Mar 2, 2009

How much time would I waste learning the overhead for a minimal C++ GUI to make the desktop equivalent of like Photoswipe, I think it's called? (Shows photos in a slideshow, asks you keep or delete.)

I'm sure it already exists, though I can't find it, and I'm sure I could knock it out in Python in a few hours, but this sounded like a simple project to step from a cursory tutorial knowledge of C++ to "an actual thing that works".

Evil_Greven
Feb 20, 2007

Whadda I got to,
whadda I got to do
to wake ya up?

To shake ya up,
to break the structure up!?
That depends on what you use... Windows has a lot of boilerplate that you have to run through, and you might end up using GDI/GDI+ for graphics.

A long time ago, I worked with GDI and tried to explain it a bit in a little tutorial, if you're interested.

It is full of terrible advice and such, but the code is pretty solid.

Adbot
ADBOT LOVES YOU

KICK BAMA KICK
Mar 2, 2009

Evil_Greven posted:

That depends on what you use... Windows has a lot of boilerplate that you have to run through, and you might end up using GDI/GDI+ for graphics.

A long time ago, I worked with GDI and tried to explain it a bit in a little tutorial, if you're interested.

It is full of terrible advice and such, but the code is pretty solid.
Cool, I will look at that. I was actually thinking Ubuntu as my primary target, but was interested in cross-platform just for the sake of learning. My first thought was Qt cause I'm modestly familiar with its Python wrappers like PySide but I don't know how much knowledge translates.

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