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
tractor fanatic
Sep 9, 2005

Pillbug

rjmccall posted:

There's no difference in layout, if that's what you mean. There's a difference in semantics at deletion time, where deleting a single object can require a virtual destructor to be called but deleting an array cannot, but again that's directed by the core division. The reason for that division is efficiency and simplicity. While the committee doesn't guarantee that the standard allocation functions will be implemented in terms of malloc and free, it does want to permit that, which would not be possible if the platform ABI required separate memory pools for single-object allocations vs. array allocations. And if the platform ABI doesn't require that, then it's basically forced to allocate extra memory with every single (non-POD) heap allocation.

that makes sense, thanks. I hadn't thought about the problem with virtual destructors between delete and delete[].

Adbot
ADBOT LOVES YOU

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
[quote="Gordon Cole"]
I've got a homework assignment that's driving me nuts. I'm implementing a compiler for a custom language that translates to C. This language supports nested functions that can reference variables in their parent functions. From what I understand, the best way to implement this is to pass a static link (a pointer to the stack frame of the enclosing function) to each function, from which you can find the variable you want by applying a constant offset.[/fixed]

There are tons of different ways to implement nested functions. There are several key points of language design which influence the choice:
  • Are captured variables captured by reference or by value?
  • Do you need to be able to take the address of the nested function? i.e., if you have an expression which names the nested function, can you do anything with it besides immediately call it? If so:
    • Does a reference to a nested function have the same type as a reference to a top-level function with the same formal signature would? If so, are there ABI constraints on the representation of that type?
    • What happens if a reference to a nested function outlives the enclosing function?
      • If this doesn't have undefined behavior, then are variables captured by reference allowed to change their address?

If all variables are captured by reference and the only thing you can do with a reference to a nested function is call it, then your basic choice is between Ugg Boots's suggestion (passing the address of every captured variable to the nested function) and Vanadium's (putting all the captured variables in a struct and passing the address of that to nested functions). Remember that you might have multiple levels of nesting.

dizzywhip
Dec 23, 2005

Ugg boots posted:

Just figure out which variables from the parent function are being used in the nested function and pass references/pointers to all of them when calling the nested function.

I guess that would work, though when we were going over the assignment in class the professor specifically mentioned that we should use a static link. Wikipedia and other places online also mention that as being the way nested functions are typically implemented. I'll probably do it this way as a last resort though.

pseudorandom name posted:

You can't predict anything about the layout of stack variables. The compiler can (and will) place them in any order it feels like, sometimes combining multiple variables into a single stack slot or never allocating any stack space at all.

That makes sense. I suppose the solution is to figure out the offset at run time then?

rjmccall posted:

There are tons of different ways to implement nested functions. There are several key points of language design which influence the choice:
  • Are captured variables captured by reference or by value?
  • Do you need to be able to take the address of the nested function? i.e., if you have an expression which names the nested function, can you do anything with it besides immediately call it? If so:
    • Does a reference to a nested function have the same type as a reference to a top-level function with the same formal signature would? If so, are there ABI constraints on the representation of that type?
    • What happens if a reference to a nested function outlives the enclosing function?
      • If this doesn't have undefined behavior, then are variables captured by reference allowed to change their address?

If all variables are captured by reference and the only thing you can do with a reference to a nested function is call it, then your basic choice is between Ugg Boots's suggestion (passing the address of every captured variable to the nested function) and Vanadium's (putting all the captured variables in a struct and passing the address of that to nested functions). Remember that you might have multiple levels of nesting.

Variables are captured by reference and functions aren't first-class objects, so all you can do with a function is call it, and you can never reference a function outside of the scope in which it was declared.

I think I'm going to try out figuring out the static link offset at run time for now, and if that doesn't work out I'll go with Ugg Boots's suggestion.

Edit: Well it looks like poo poo but it works. woop :toot:

dizzywhip fucked around with this message at 21:17 on May 6, 2011

Paniolo
Oct 9, 2007

Heads will roll.
code:
template <typename T>
class Foo
{
   template <typename U>
   Foo(const Foo<U>& cpy);
};

template <typename T, typename U>
Foo<T>::Foo(const Foo<U>& cpy)
{
}

int main()
{
   return 0;
}
Is there any legal way to put the implementation of the constructor outside of the class, ala the commented out section? I know it works if the constructor's body is inside the class definition, just curious why the above fails.

tractor fanatic
Sep 9, 2005

Pillbug
You need to separate the template like so:

code:
template <typename T>
class Foo
{
   template <typename U>
   Foo(const Foo<U>& cpy);
};

template <typename T> template <typename U>
Foo<T>::Foo(const Foo<U>& cpy)
{
}

int main()
{
   return 0;
}

Paniolo
Oct 9, 2007

Heads will roll.

tractor fanatic posted:

You need to separate the template like so:

code:
template <typename T>
class Foo
{
   template <typename U>
   Foo(const Foo<U>& cpy);
};

template <typename T> template <typename U>
Foo<T>::Foo(const Foo<U>& cpy)
{
}

int main()
{
   return 0;
}

Thanks! Hadn't seen the double template syntax before.

tractor fanatic
Sep 9, 2005

Pillbug
I'm curious now if you can explicitly call a template member constructor, like is there any way to get this to work:

code:
template <typename T>
class Foo
{
public:
   template <typename U>
   Foo(int a);
};

template <typename T> template <typename U>
Foo<T>::Foo(int a)
{
}

int main()
{
   Foo<int> c(5);  // what do i do here?
   return 0;
}

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
Nope.

Eugenics
Mar 25, 2007
Because I'm better than you
I'm trying to find a uniform random number generator to use for a little program I need to write. I have previous experience with the generic random number generator in C, but when I googled information about it there was some stuff popping up about how it doesn't actually produce uniform values if you want to get values between 0 and 1. I also looked at the Boost library, but I don't have any OO knowledge so all the stuff about templates just flew way over my head.

Basically, I need a URNG that I can get values from 0 to 1, does anybody have any suggestions?

pr0metheus
Dec 5, 2010

Eugenics posted:

I'm trying to find a uniform random number generator to use for a little program I need to write. I have previous experience with the generic random number generator in C, but when I googled information about it there was some stuff popping up about how it doesn't actually produce uniform values if you want to get values between 0 and 1. I also looked at the Boost library, but I don't have any OO knowledge so all the stuff about templates just flew way over my head.

Basically, I need a URNG that I can get values from 0 to 1, does anybody have any suggestions?

Just generate a random integer then divide by the maximum number that rand() can output? That should get you a value between 0 and 1 that is uniformly distributed.

darkhand
Jan 18, 2010

This beard just won't do!
In an assignment I had to create a Vector class using arrays and pointers to Student objects (Vector had knowledge of Students). In a new assignment, we have to create a templated Vector class using linked-list, and vector shouldn't have knowledge of Students.

In the old assignment we could use Remove(int studentID) to remove Students from the vector; it would iterate through the array of pointers to Students and find the Student with studentID.

How would I do that in a generic way? Adding is fine because I set a node to point to a passed-in Student generically. But how do I find a specific Student and remove them from the vector?

Having a Remove(T& delObject) seems kind-of stupid because the caller would have to remember objects and defeat the purpose of a vector.

Any tips on this?

Sedro
Dec 31, 2008
You can either use a templated "key" type (student ID was the key for your Student class) but that would make your type more like a map, or simply have a Remove(int index).

darkhand
Jan 18, 2010

This beard just won't do!

Sedro posted:

You can either use a templated "key" type (student ID was the key for your Student class) but that would make your type more like a map, or simply have a Remove(int index).

Yeah I'm trying to wrap my head around implementing Remove(int index) but at some point the caller has to know the index of the Student. So Vector could have a T Get(int index) that returns the object at index in the list. And the caller can figure out if it's the right Student or not?

Jabor
Jul 16, 2010

#1 Loser at SpaceChem

darkhand posted:

Yeah I'm trying to wrap my head around implementing Remove(int index) but at some point the caller has to know the index of the Student. So Vector could have a T Get(int index) that returns the object at index in the list. And the caller can figure out if it's the right Student or not?

Doing it this way (caller iterates over the list to find the right one, then removes it) is feasible, yes.

But doing it the specific way you describe (through a random-access get method rather than an iterator) isn't very nice, particularly for a linked list implementation.

TasteMyHouse
Dec 21, 2006

darkhand posted:

Yeah I'm trying to wrap my head around implementing Remove(int index) but at some point the caller has to know the index of the Student. So Vector could have a T Get(int index) that returns the object at index in the list. And the caller can figure out if it's the right Student or not?

You could have a class that takes objects of T and then objects of U where "T" is the type contained in your Vector, and U is the key, and then returns a bool indicating if that key matches your object, then pass an instance of this class to a remove function on your vector.


So like, if you wanna indentify a student by id, you'd write a class like this

code:
class HasKey
{
   bool operator()(Student s,int k) const
   {
        //logic here that checks if student S has key K and returns true or false respectively
   }
};
then you can either have a template parameter indicating this helper class, or have all of your key-ing classes derive from a base class or whatever.

TasteMyHouse fucked around with this message at 00:13 on May 9, 2011

darkhand
Jan 18, 2010

This beard just won't do!
Thanks for the help! I'll see what I can do with it.

Modern Pragmatist
Aug 20, 2008
I'm working on converting a bunch of algorithms from Matlab to C because Matlab is painfully slow at pretty much everything. For loops aren't nearly as inefficient in C as they are in Matlab but all of the Matlab code utilizes lots of linear algebra routines. Would using a package like LAPACK be beneficial for both speed and conversion?

BigRedDot
Mar 6, 2008

Modern Pragmatist posted:

I'm working on converting a bunch of algorithms from Matlab to C because Matlab is painfully slow at pretty much everything. For loops aren't nearly as inefficient in C as they are in Matlab but all of the Matlab code utilizes lots of linear algebra routines. Would using a package like LAPACK be beneficial for both speed and conversion?

I'm not a matlab fan by any stretch, but if you've got lots of for loops in your matlab code, you're doing it wrong. That said, if you are converting matlab to C, then yes you should be utilizing BLAS or LAPACK or Atlas or FFTW or whatever already-existing, mature, well-tested numerical libraries are appropriate for your application. For speed and conversion, and most of all, correctness. There's pretty much no chance your 11-sided, elliptically-shaped reinvented wheel will be as robust off the bat...

schnarf
Jun 1, 2002
I WIN.

Modern Pragmatist posted:

I'm working on converting a bunch of algorithms from Matlab to C because Matlab is painfully slow at pretty much everything. For loops aren't nearly as inefficient in C as they are in Matlab but all of the Matlab code utilizes lots of linear algebra routines. Would using a package like LAPACK be beneficial for both speed and conversion?
LAPACK et. al. are good. It'll be a waste of time for you to write all that stuff. If you have any interest in using C++, Eigen is probably pretty great too, and it integrates nicely with the language and uses templates to make fast code. Compile times are slow though.

pr0metheus
Dec 5, 2010
What are good unit testing tools for C++? I have been looking into boost's unit testing framework.

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!
I have been compelled to write some Python wrappers for some code I've been using. This has been slow-going for awhile but I am slowly starting to wrap my head around the Boost Python wrappers. Where I am stuck is how I could wrap bit fields. I actually didn't even know about bit fields until just now. The Boost Python bindings work with references to the properties or functions being wrapped, but one cannot take a reference to a bit field according to what I know of C++. So what could I do to appease the beast if:

1. The class in question gets subclassed later on and is generally tossed around, so I can't just subclass off some bonus methods.
2. I can't change the original source and maintain interoperability.

I am hoping theres some Boost Python voodoo to provide something but I wouldn't know what.

Hot Dog Day #55
May 22, 2003

The noblest of all dogs is the hot-dog; it feeds the hand that bites it.

pr0metheus posted:

What are good unit testing tools for C++? I have been looking into boost's unit testing framework.

I like google's googletest.

OddObserver
Apr 3, 2009

Rocko Bonaparte posted:

I have been compelled to write some Python wrappers for some code I've been using. This has been slow-going for awhile but I am slowly starting to wrap my head around the Boost Python wrappers. Where I am stuck is how I could wrap bit fields. I actually didn't even know about bit fields until just now. The Boost Python bindings work with references to the properties or functions being wrapped, but one cannot take a reference to a bit field according to what I know of C++.

Why not just add accessor functions and wrap those?

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!

OddObserver posted:

Why not just add accessor functions and wrap those?
I should have specified; I am trying to wrap external calls, so I not necessarily at liberty to change that code.

That being said, I saw they provided a function for adjusting the fields based on enum values, and that saved my butt. However, I had to basically give up when I realized I'd basically have to wrap a huge portion of this library just to do a basic thing, so I am taking a different approach.

Harokey
Jun 12, 2003

Memory is RAM! Oh dear!
I'm a maintainer of a library, which is all written in C++ and the interface is also written in C++. Is there an easy way to generate a pure C library from this? One of my users is planning on spending the summer doing this, but if there's a very straightforward way to do it I'd be interested to know.

Melted_Igloo
Nov 26, 2007

Harokey posted:

I'm a maintainer of a library, which is all written in C++ and the interface is also written in C++. Is there an easy way to generate a pure C library from this? One of my users is planning on spending the summer doing this, but if there's a very straightforward way to do it I'd be interested to know.

Well if all your functions are in a header file, then to let C use them you have to declare it like this:

extern "C" {
#include "MyCHeader.h"
}

it will prevent C++ name mangling

Quebec Bagnet
Apr 28, 2009

mess with the honk
you get the bonk
Lipstick Apathy

Harokey posted:

I'm a maintainer of a library, which is all written in C++ and the interface is also written in C++. Is there an easy way to generate a pure C library from this? One of my users is planning on spending the summer doing this, but if there's a very straightforward way to do it I'd be interested to know.

At one point SWIG was going to be able to output C but I don't know whatever came of that project. I think it was a Google Summer of Code thing that was never finished.

floWenoL
Oct 23, 2002

Melted_Igloo posted:

Well if all your functions are in a header file, then to let C use them you have to declare it like this:

extern "C" {
#include "MyCHeader.h"
}

it will prevent C++ name mangling

I don't think you understand what Harokey is asking.

Melted_Igloo
Nov 26, 2007
You mean changing C++ code into C code?

Im sure you could write a parser to do that,
you would have to make class into struct and all functions public

also ClassFoo::Bar() into ClassFoo_Bar

but you still have the problem where C only allows variable definitions at the beginning of the function
You would basically go through all the compiler errors one by one and fix them
(or find a tool somewhere on the web if that sounds too hard)

Melted_Igloo fucked around with this message at 04:29 on May 18, 2011

Mr.Radar
Nov 5, 2005

You guys aren't going to believe this, but that guy is our games teacher.
What he's looking for is an easy means of wrapping a C++ library with a C interface. I.e. if your library has an interface of
code:
class Foo {
    int x;
public:
    Foo();
    Foo(int in_x);
    const Bar &frob(int z);
};
You'd write code like this:
code:
/*Header*/
struct Foo;
struct Foo *Foo_construct_default();
struct Foo *Foo_construct_int(int in_x);
struct Foo *Foo_copy(const struct Foo *);
void Foo_destruct(struct Foo *);
const struct Bar *Foo_frob(struct Foo *self, int z);
/* C wrapper implementation file (in C++) */
extern "C" {
#include "c_interface.h"
}
#include "Foo.h"
extern "C" {
struct Foo *Foo_construct_default() {
    return new Foo();
}

struct Foo *Foo_construct_int(int in_x) {
    return new Foo(in_x);
}

struct Foo *Foo_copy(const struct Foo *in) {
    return new Foo(*in);
}

void Foo_destruct(struct Foo *in) {
    delete in;
}

const struct Bar *Foo_frob(struct Foo *self, int z) {
    return &self->frob(z);
}
}
And it's used as:
code:
/* C program */
#include "c_interface.h"

int main(int argc, char *argv[]) {
    struct Foo *f = Foo_construct_default();
    const struct Bar *b = Foo_frob(f, 5);
    /* stuff */
    Foo_destruct(f);
}
As you can see, this is very tedious to do which is why Harokey is looking for a tool that can do it for him (or at least do most of it).

Mr.Radar fucked around with this message at 04:48 on May 18, 2011

shrughes
Oct 11, 2008

(call/cc call/cc)
Take the object file output and demangle the names.

Edit: Or, ffs, do it by hand. There's no way it should take all summer.

pseudorandom name
May 6, 2007

If you're really clever and your C++ API is simple enough, you can go the COM route and make the C struct expose the vtable directly.

Harokey
Jun 12, 2003

Memory is RAM! Oh dear!

Mr.Radar posted:

What he's looking for is an easy means of wrapping a C++ library with a C interface.

This is exactly what I want. Hopefully there's a program that can do this automatically.

Also, I'd rather some tool to do this so that I don't have to make the changes in two places whenever I add something or change an interface. It'd be ideal if they were automatically generated at build time, maybe by CMake or something.


bear shark posted:

At one point SWIG was going to be able to output C but I don't know whatever came of that project. I think it was a Google Summer of Code thing that was never finished.

I'm aware of swig, but I'm not sure if it could do this or not. In the not so distant future I'd like to toy with the idea of generating python and other bindings. This will actually be quite entertaining as my project is a C++ port of a python project. If swig was able to generate a C library from C++, that would be great. I looked very briefly at it, and didn't see that it was possible, but I didn't look long, and would love to be proven wrong here.

Harokey fucked around with this message at 02:46 on May 19, 2011

Optimus Prime Ribs
Jul 25, 2007

I was mucking around with C++ and came across something that is not making any sense to me.
Could someone explain to me why a value of "zero" is being output: http://codepad.org/nhAwKd6V

Is this something to do with std::cout or exponents when used in C++? Or what?
This is really making me go :psyduck:.

edit:

Google solved my problem. I don't know why I never before figured out that "^" is the XOR operator.
I'm pretty dense sometimes. :downs:

Optimus Prime Ribs fucked around with this message at 07:50 on May 20, 2011

ctz
Feb 6, 2003
^ is bitwise XOR, not exponentiation. y ^ y evaluaties to 0 for all y.

C and C++ do not have exponentiation operators, instead there are functions in the standard library (pow, which is defined only for floating point numbers).

Staggy
Mar 20, 2008

Said little bitch, you can't fuck with me if you wanted to
These expensive
These is red bottoms
These is bloody shoes


I'm having a bit of trouble with templates - they're not something I've used much before.

I have this:
code:
template <class T>
void BinaryFile::Write( T data )
{
	if ( !_Stream.is_open() )
		return;

	char* Mem = new char[ sizeof( T ) ];
	Mem[0] = T;
	_Stream.write( Mem , sizeof( T ) );
	delete [] Mem;

	Advance( sizeof( T ) );
};
This is my (very very basic) attempt at making binary file IO a tiny bit easier/cleaner. There is also a matching Read():
code:
template <class T>
T BinaryFile::Read()	
{
	if ( !_Stream.is_open() )
		return;

	char* Mem = new char[ sizeof( T ) ];
	_Stream.read( Mem , sizeof( T ) );
	
	T Temp = (T)Mem[0];
	delete [] Mem;

        Advance( sizeof( T ) );
	return Temp;

};
The problem is that I get errors when I try and use them. This is how I've tried to use them:
code:
bool World::Load( std::string file )
{
	BinaryFile File;
	if ( !File.Open( file ) )
	{
		return false;
	}

	int Types = File.Read<int>();	//	num file types

	for ( int i = 0; i < Types; i++ )
		AddTileType( File.Read<Tile>() );

	SetWidth( File.Read<int>() );
	SetHeight( File.Read<int>() );

	for ( int x = 0; x < GetWidth(); x++ )
		for ( int y = 0; y < GetHeight(); y++ )
			SetTile( x , y , File.Read<int>() );

	File.Close();

	return true;
};
and the errors are:

quote:

1>World.obj : error LNK2019: unresolved external symbol "public: struct Tile __thiscall BinaryFile::Read<struct Tile>(void)" (??$Read@UTile@@@BinaryFile@@QAE?AUTile@@XZ) referenced in function "public: bool __thiscall World::Load(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?Load@World@@QAE_NV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
1>World.obj : error LNK2019: unresolved external symbol "public: int __thiscall BinaryFile::Read<int>(void)" (??$Read@H@BinaryFile@@QAEHXZ) referenced in function "public: bool __thiscall World::Load(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?Load@World@@QAE_NV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
Where am I going wrong with this?

brosmike
Jun 26, 2009
The most likely cause is that you're not including the function template definition in your World source file. Since function templates are not instantiated for particular template types until they're actually used, you can't just include declarations in a header file and leave the implementation for the linker to deal with. The implementation for the particular T you use literally does not exist for the linker to find unless the compiler creates it for you, which it doesn't know how to do if you haven't included the template definition.

TLDR: Put definitions of function and class templates in header files.

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!
I've never really thought about that - where does the compiler/linker put the functions generated from a template?

If, for example, I have a template defined in header "mytemplate.h" and then I have mytemplate<int> used in both foo.cpp and bar.cpp, which of those object files does mytemplate<int> end up compiled into? Or both? Or some special separate place?

Plorkyeran
Mar 22, 2007

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

Staggy posted:

code:
	char* Mem = new char[ sizeof( T ) ];
	Mem[0] = T;
	_Stream.write( Mem , sizeof( T ) );
	delete [] Mem;
This code is nonsensical and shouldn't even compile. There's no reason to copy the passed object into a temporary buffer, and this isn't even a valid way of doing that.

roomforthetuna posted:

If, for example, I have a template defined in header "mytemplate.h" and then I have mytemplate<int> used in both foo.cpp and bar.cpp, which of those object files does mytemplate<int> end up compiled into? Or both? Or some special separate place?
Both. The linker throws away the extra copies.

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!

Plorkyeran posted:

Both. The linker throws away the extra copies.
Thanks. And ah, of course, that would be the same way functions defined in the class header would be treated, duh.

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