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
Jabor
Jul 16, 2010

#1 Loser at SpaceChem

Gerblyn posted:

You've probably already tried this, but I've had similar issues in MSVC which I managed to fix simply by doing a Rebuild All.

Considering that "two translation units disagreeing about something" is usually caused by something not being recompiled when it should, this is probably a good idea.

I mean, it doesn't fix the actual problem of "your dependency setup is probably wrong somewhere", but it at least fixes the symptoms.

Adbot
ADBOT LOVES YOU

MarsMattel
May 25, 2001

God, I've heard about those cults Ted. People dressing up in black and saying Our Lord's going to come back and save us all.
This is a Visual Studio specific question. I have a very strange problem when using the VS debugger: if I set a breakpoint in an application (using __debugbreak() or an int 3) and launch the application without a debugger attached (e.g. Debug -> Start Without Debugging) and then attach a debugger when the breakpoint is hit, once I try to continue the application in the VS debugger it raises the error:

Visual Studio posted:

Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.

If I start the application with the debugger already attached (i.e. Debug -> Start Debugging) then the error is not present. Similarly if I run the application normally without any debugger involvement then the application runs normally.

At first I thought it was a problem in a particular application, but I see it with every application. Even something as simple as this will have the error raised:

code:
#include <stdio.h>

void f()
{
	printf("f\n");
}

int main(int argc, char** argv)
{
	__debugbreak();
	f();
	return 0;
}
I thought it must be something in my environment that is causing the problem. This is my work machine so there are all sorts of SDKs and compilers etc installed, and one or two of them acting up seemed plausible. However, I've spent most of the afternoon uninstalling stuff without any luck.

Has anyone had a problem like this before?

raminasi
Jan 25, 2005

a last drink with no ice
I don't know the source of the problem, but why aren't you just using assert(false) (or, you know, a breakpoint?)

MarsMattel
May 25, 2001

God, I've heard about those cults Ted. People dressing up in black and saying Our Lord's going to come back and save us all.
I'm not using assert because I don't want an assert, I want a breakpoint.

I'm using the __debugbreak() intrinsic because I want to debug it running as part of a tool chain. Sometime's that's a pain in the arse to do, most of the time it's just quicker to insert breakpoint, build and run the test case again. There's also the chance that you've not quite correctly recreated the environment so being able to hit a "physical" breakpoint is quite handy.

Paniolo
Oct 9, 2007

Heads will roll.
Have you tried using WinDbg instead of Visual Studio? That would make it possible to isolate a VS bug.

Zhentar
Sep 28, 2003

Brilliant Master Genius
Also you can use the Image File Execution Options to hook the debugger when your executable is launched.

InAndOutBrennan
Dec 11, 2008
If I have a vector<vector<char> > and do a push_back with a new vector<char>.

Will that invalidate any vector<char>::iterators to previously stored content?

chglcu
May 17, 2007

I'm so bored with the USA.
I think it will if the push causes the vector to reallocate. If instead you stored pointers to the nested vectors, their iterators would be safe since their contents wouldn't be moved around when the containing vector was reallocated.

Optimus Prime Ribs
Jul 25, 2007

woptsufp posted:

If I have a vector<vector<char> > and do a push_back with a new vector<char>.

Will that invalidate any vector<char>::iterators to previously stored content?

I wrote some test code to find out, and it worked fine in Visual Studio, but once I ran it on Codepad (which uses GCC) it bricked.
I don't know poo poo about GCC, so take from that what you will.

This is the code, GCC error included: http://codepad.org/7ikUJ4Xh

To anyone who is familiar with GCC: why is it getting pissed off at me defining the variable "itr" before all the push backs of the vectors?
This something just specific to how GCC handles C++, or Visual Studio's compiler ignoring an error that it shouldn't be?

InAndOutBrennan
Dec 11, 2008
It compiles fine here but it segfaults when run so it seems the iterators are invalidated. I suspected as much, thanks for the help.

Bugger.

(was at work when posting the question, with no compiler in sight)

Gerblyn
Apr 4, 2007

"TO BATTLE!"
Fun Shoe
You could just use vector<vector<char>*> (or smart pointers) with dynamically allocated vector<char>s instead, your iterators would be fine then.

Edit: Sorry Prolecat, didn't realise I was parroting what you'd already suggested.

Gerblyn fucked around with this message at 18:19 on Jan 26, 2012

raminasi
Jan 25, 2005

a last drink with no ice
You can also reserve enough space before getting any iterators (if it's possible to structure your logic that way).

InAndOutBrennan
Dec 11, 2008

Gerblyn posted:

You could just use vector<vector<char>*> (or smart pointers) with dynamically allocated vector<char>s instead, your iterators would be fine then.

prolecat posted:

If instead you stored pointers to the nested vectors, their iterators would be safe since their contents wouldn't be moved around when the containing vector was reallocated.

Yeah this is probably the way I'm heading. Thanks again.

floWenoL
Oct 23, 2002

GrumpyDoctor posted:

You can also reserve enough space before getting any iterators (if it's possible to structure your logic that way).

That doesn't help if you're pushing back the vector itself (and thus making a copy).

Brecht
Nov 7, 2009

GrumpyDoctor posted:

You can also reserve enough space before getting any iterators (if it's possible to structure your logic that way).
That's just an implementation detail. It may work but you shouldn't rely on it, as modifying a vector during iteration is undefined behavior (AFAIK).

Plorkyeran
Mar 22, 2007

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

Brecht posted:

That's just an implementation detail. It may work but you shouldn't rely on it, as modifying a vector during iteration is undefined behavior (AFAIK).
Nope, the standard requires that appending to a vector only invalidates iterators if it results in the size exceeding the previous capacity.

(vector::reserve)

23.3.6.3.5 posted:

Reallocation invalidates all the references, pointers, and iterators referring to the elements in the sequence. It is guaranteed that no reallocation takes place during insertions that happen after a call to reserve() until the time when an insertion would make the size of the vector greater than
the value of capacity().

(vector::push_back/insert)

23.3.6.5.1 posted:

Causes reallocation if the new size is greater than the old capacity. If no reallocation happens,all the iterators and references before the insertion point remain valid.

Brecht
Nov 7, 2009

Plorkyeran posted:

Nope, the standard requires that appending to a vector only invalidates iterators if it results in the size exceeding the previous capacity.

(vector::reserve)

(vector::push_back/insert)
(slams fist) drat my fallible human memory

Gerblyn
Apr 4, 2007

"TO BATTLE!"
Fun Shoe
From a design perspective, I never really like relying on reserve to prevent allocations in that way. It's the kind of thing that fixes your problems, and then a few months later you get a crash because it turns out you didn't reserve enough space. Of course, this can be fixed by having:

pre:
assert(myVector.size()<myVector.capacity()) 
before every insertion, it just seems a bit inelegant is all.

MarsMattel
May 25, 2001

God, I've heard about those cults Ted. People dressing up in black and saying Our Lord's going to come back and save us all.
I wasn't able to get to the bottom of my bizarre debugger behaviour. I uninstalled everything that I thought could be interfering (other versions of VS, VS plugins, etc.) and still the problem persisted. I then uninstalled VS 2005 (which I was using to build and debug the code) and reinstalled it and the problem was still there! I then deleted every VisualStudio registry entry (that wasn't do to with a file association). On restarting VS 2005 I was greeted with the first time setup screen, but again the problem persisted. After that I re-installed Windows7 (which to my surprise left most of my dev environment intact), installed VS2005 and the problem was gone. :iiam:

That Turkey Story
Mar 30, 2003

woptsufp posted:

If I have a vector<vector<char> > and do a push_back with a new vector<char>.

Will that invalidate any vector<char>::iterators to previously stored content?

With a C++03 STL, yes, they will be invalidated if you exceed capacity. In a C++11 STL, they should not be (though I admittedly haven't checked the standard on this), since the vectors are moved instead of copied. Again, don't quote me on that unless someone looks it up, but that seems very reasonable.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
I don't think that's guaranteed; among other things, it would forbid inline allocation of small vectors.

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed
I can't find anything that says that vectors must use the move constructor for reallocation when possible, but I may just be looking in the wrong place.

That Turkey Story
Mar 30, 2003

rjmccall posted:

I don't think that's guaranteed; among other things, it would forbid inline allocation of small vectors.

Ahh, true.

Edit: Actually, this is interesting.

"[container.requirements.general p8 posted:

"]The expression a.swap(b), for containers a and b of a standard container type other than array, shall exchange the values of a and b without invoking any move, copy, or swap operations on the individual container elements.

...

Every iterator referring to an element in one container before the swap shall refer to the same element in the other container after the swap. It is unspecified whether an iterator with value a.end() before the swap will have value b.end() after the swap.

Emphasis, mine.

While not explicitly stated, this implies that the small buffer optimization cannot be used with vectors. I do, however, still agree with you that the standard does not guarantee that vector iterators remain valid upon a move operation, unless I am missing where that is explicitly stated.

Plorkyeran posted:

I can't find anything that says that vectors must use the move constructor for reallocation when possible, but I may just be looking in the wrong place.

I'm pretty sure that this is required, only because it isn't uncommon that move operations of types preserve relationships whereas copies do not. If it's not required, then you can never rely on the behavior in those cases. I'll look further, but IIRC as long as you have a no-throw move operation it is supposed to be used. I wouldn't be surprised if I'm wrong here, but I'd be disappointed if I am.

That Turkey Story fucked around with this message at 02:13 on Jan 27, 2012

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

That Turkey Story posted:

While not explicitly stated, this implies that the small buffer optimization cannot be used with vectors.

Very interesting, and a pity. Fortunately, this does not seem to apply to strings.

That Turkey Story posted:

I do, however, still agree with you that the standard does not guarantee that vector iterators remain valid upon a move operation, unless I am missing where that is explicitly stated.

Yeah, I don't see this guarantee anywhere either.

Plorkyeran
Mar 22, 2007

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

That Turkey Story posted:

I'm pretty sure that this is required, only because it isn't uncommon that move operations of types preserve relationships whereas copies do not. If it's not required, then you can never rely on the behavior in those cases. I'll look further, but IIRC as long as you have a no-throw move operation it is supposed to be used. I wouldn't be surprised if I'm wrong here, but I'd be disappointed if I am.
There's a few places that seem to imply that the copy constructor should be used only used if there's no move constructor, so do hope I'm just failing to find the spot where it's actually mandated.

Good Will Punting
Aug 30, 2009

And as the curtain falls
Just know you did it all except lift weights
Quick question on merge sort that shouldn't be too difficult for you dudes:

My professor gave us an example implementation in pseudo-code and before I implement it in C++, I stepped through it with a pen and paper. When I went through it, however, it seems to behave in a differenent order than the diagram he showed us. (see here: http://en.m.wikipedia.org/wiki/File:Merge-sort-example-300px.gif). Take n = 8 to make things easy. When I put that through the pseudo-code it sorted the left-most two, then the next two, then all 4 of those, then the 5th and 6th in, then the 7th and 8th in, then those four, then merged them all. I've stepped through twice now and gotten the same thing, so I just wanted to check with you guys and see if this is normal. Sorry if this is the wrong thread, tia.

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed
The four top-level sorts don't depend on each other in any way, so they can be done in whatever order you want.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
It's also exactly what you'd expect from the natural recursive solution: 1) divide the list in half, 2) sort the first half, 3) sort the second half, 4) merge the results. So for any given segment, all the work involving its first half will be done before all the work involving its second half. But as plorkeyran says, it doesn't matter because the sub-sorts are independent; they just have to happen before the final merge.

A MIRACLE
Sep 17, 2007

All right. It's Saturday night; I have no date, a two-liter bottle of Shasta and my all-Rush mix-tape... Let's rock.

What does it mean if printf("%s") literally prints "(NULL)"? Encountered this while trying to write/debug a chomp function in C.

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed
It means that the uninitialized memory it's trying to read a char* from contains NULL.

pseudorandom name
May 6, 2007

Note that this is a glibc extension to the *printf functions and other C libraries will probably just crash when passed a NULL pointer.

shodanjr_gr
Nov 20, 2007
I've encountered some behavior discrepancy between MSVC++ 2008 and Xcode 4 C++.

I have a couple of structs

code:

struct foo 
{
 //fields
}

struct bar
{
//fields
}
And a class

code:

class MyClass
{

Foo _foo;
Bar _bar;
}
I want to invoke the initializer for the structs when creating an instance of my class so I changed the definition to:

code:
class MyClass
{

Foo _foo = {};
Bar _bar = {};
}
This last segment compiles fine in Xcode 4 but doesn't compile in MSVC (the compiler goes crazy when encountering the {}). What would be the proper way to work around this?

Paniolo
Oct 9, 2007

Heads will roll.
Can anyone explain the following behavior?

code:
template <typename T>
struct return_type
{
    template <typename U>
    static auto check_type(U* t) -> decltype((*t)())
    {
    }
    static void check_type(...)
    {
    }
    typedef decltype(return_type::check_type((T*)0)) type;
};

int foo()
{
    return 0;
}

boost::optional<int> bar()
{
    return 0;
}

TEST(aaa, aaaa)
{
    static_assert(boost::is_same<typename return_type<decltype(&foo)>::type,
                                 int>::value, "A");
    static_assert(boost::is_same<typename return_type<decltype(&bar)>::type,
                                 boost::optional<int>>::value, "B");
    static_assert(boost::is_same<typename return_type<decltype(&bar)>::type,
                                 boost::optional<int>&>::value == false, "C");
}
This errors out on B and C. For some reason, it's deducing the return value of bar as a reference, although it isn't doing that for foo.

edit: ahahaha, I found something that fixes it:

code:
    typedef decltype(0, return_type::check_type((T*)0)) type;
Adding the "0, " makes it deduce the type correctly. Why in the everloving gently caress that makes it work, I have no idea. Got the idea from here: http://stackoverflow.com/questions/4970959/how-can-i-use-decltype-to-get-the-type-of-a-reference

Paniolo fucked around with this message at 04:00 on Jan 29, 2012

nielsm
Jun 1, 2009



shodanjr_gr posted:

I want to invoke the initializer for the structs when creating an instance of my class so I changed the definition to:

code:
class MyClass
{

Foo _foo = {};
Bar _bar = {};
}
This last segment compiles fine in Xcode 4 but doesn't compile in MSVC (the compiler goes crazy when encountering the {}). What would be the proper way to work around this?

I don't think that's supposed to be legal.

The default (no-arg) constructors, if any, for your structs should already be run when an instance of your class is constructed. If you want to use a different constructor, define a constructor for your class and use initialiser syntax to construct the structs:

code:
struct Foo {
  int x;
  Foo() : x(1) { } // default constructor, field x initialised to 1
  Foo(int x) : x(x) { } // field x initialised to constructor argument x
};
struct Bar {
  int y;
  // no constructor, compiler supplies a default constructor that runs
  // the default constructors on all fields
  // (default constructor for ints sets them to 0)
}
class MyClass {
  Foo foo;
  Bar bar;
public:
  MyClass(int x = 5) : foo(x), bar() { } // pass x to Foo constructor, run Bar default constructor
};

That Turkey Story
Mar 30, 2003

nielsm posted:

I don't think that's supposed to be legal.
I'm pretty sure it's legal in C++11. That'd be an inline default member initialization. Microsoft probably just hasn't implemented it yet.

Paniolo posted:

Can anyone explain the following behavior?

code:
template <typename T>
struct return_type
{
    template <typename U>
    static auto check_type(U* t) -> decltype((*t)())
    {
    }
    static void check_type(...)
    {
    }
    typedef decltype(return_type::check_type((T*)0)) type;
};

int foo()
{
    return 0;
}

boost::optional<int> bar()
{
    return 0;
}

TEST(aaa, aaaa)
{
    static_assert(boost::is_same<typename return_type<decltype(&foo)>::type,
                                 int>::value, "A");
    static_assert(boost::is_same<typename return_type<decltype(&bar)>::type,
                                 boost::optional<int>>::value, "B");
    static_assert(boost::is_same<typename return_type<decltype(&bar)>::type,
                                 boost::optional<int>&>::value == false, "C");
}
This errors out on B and C. For some reason, it's deducing the return value of bar as a reference, although it isn't doing that for foo.

That looks like it should work on a compliant compiler, though it's an unnecessarily complicated implementation. Before going into it, though, why do you want this metafunction to begin with? If your uses are anything like your tests, why not just do decltype(foo()) or decltype(bar()) where it's needed rather than pushing it off to a metafunction? It's simpler for everyone -- coder, reader, and compiler.

If you really want a metafunction, why not just do simply typedef decltype(std::declval<T>()()) type; as the only line of the metafunction definition (or use a partial specialization, or boost's function traits, both of which will work with functions that take multiple arguments rather than only ones which take no arguments)? You shouldn't need those member functions in your implementation at all. You can also get rid of explicitly taking the address of the function when using the metafunction if you want, pending you update the implementation, since decltype works on raw functions just fine.

Anyway, again, you probably don't need the metafunction at all. decltype on its own already does what you are trying to do and is very concise.

Paniolo
Oct 9, 2007

Heads will roll.

That Turkey Story posted:

Anyway, again, you probably don't need the metafunction at all. decltype on its own already does what you are trying to do and is very concise.

Visual C++ doesn't currently allow you to get a dependent type from a decltype expression:

code:
boost::optional<int> o;
decltype(o)::value_type i = 0;
// error C2039: 'value_type' : is not a member of '`global namespace''
The metafunction works around this limitation. It's also cleaner, IMO, than the mess you get trying to decltype a callable with multiple parameters:

code:
typedef decltype((*(F*)0)((*(T*)0, *(U*)0))) my_type;
// vs.
typedef typename return_value<F, T, U>::type my_type;
And it defaults to void if not callable with the given paramters, instead of causing a substitution failure, which is needed in my particular use case.

edit: I wasn't aware of declval, thanks for pointing that out.

Paniolo fucked around with this message at 05:11 on Jan 29, 2012

Paniolo
Oct 9, 2007

Heads will roll.
Visual C++ also seems to have an issue where if template matching fails within decltype it resolves to int and continues to compile, instead of giving an error. If that happens it also prevents SFNAE from occurring. Very annoying.

mobby_6kl
Aug 9, 2009

by Fluffdaddy
Is there a plugin or something for Visual Studio that would (help) visualize some basic data structures, like linked lists or trees? I've just spent a few hours debugging a doubly linked circular list that looped where it wasn't supposed to. Having a visual representation would make it immediately clear which nodes are misbehaving.

In this case it turned out that I was sometimes inserting the wrong node because I had "i =+ 3" instead of "i += 3" hidden somewhere, but regardless of my retardation something like this would still be very helpful

litghost
May 26, 2004
Builder

mobby_6kl posted:

Is there a plugin or something for Visual Studio that would (help) visualize some basic data structures, like linked lists or trees? I've just spent a few hours debugging a doubly linked circular list that looped where it wasn't supposed to. Having a visual representation would make it immediately clear which nodes are misbehaving.

In this case it turned out that I was sometimes inserting the wrong node because I had "i =+ 3" instead of "i += 3" hidden somewhere, but regardless of my retardation something like this would still be very helpful

Visual Studio has a file which tells the debugger how to display types in Watch (STL string, vector, list, map, pair, etc). http://msdn.microsoft.com/en-us/library/zf0e8s14.aspx You can use this to have the debugger expand your linked list into an array, or whatever. This is how VS expands STL objects, etc.

litghost fucked around with this message at 17:31 on Jan 29, 2012

Adbot
ADBOT LOVES YOU

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

mobby_6kl posted:

In this case it turned out that I was sometimes inserting the wrong node because I had "i =+ 3" instead of "i += 3" hidden somewhere

Not that it helps you at all, but Clang warns about this.

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