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
Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh
Here's a trace of what happens in your code (reordered slightly):
code:
int main()
{
	char * str1 = "Hello!";       // 1: str1 == 0xcafebabe
	char * str3;                  // 2: str2 == 0xdeadbeef
	copyString(str2, str1);       // 3: pass in 0xdeadbeef and 0xcafebabe
                                      // 6: str2 is still 0xdeadbeef here
	cout << "str1= " << str1 << endl;
	cout << "str2= " << str2 << endl;
	// delete [] str2;
	return 0;
}

void copyString(char * str2, const char * str1)
{	                              // 4: set new variables str2 = 0xdeadbeef, str1 = 0xcafebabe
	// ...
	str2 = new char [size+1];     // 5: set str2 = 0xdefec8ed
	// ...
}
str1 and str2 are just numbers and passing them into copyString makes a copy of those numbers. The C-style way varies, but the easiest way would be to pass in char *& str2 to get reference semantics.

Adbot
ADBOT LOVES YOU

dis astranagant
Dec 14, 2006

I am currently picking up a little c under unix for a class but can't for the life of me figure out how to work with files. I need to spit out an array into a csv file but I just can't seem to find anything coherent to help. I'm just not sure what functions to use to create and write to the file.

dis astranagant fucked around with this message at 04:14 on Oct 3, 2008

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh
It's exactly the same as printing to STDOUT, only you use fprintf. :confused:

cronio
Feb 15, 2002
Drifter
The first result to a google search for "C file output":

http://www.cs.bu.edu/teaching/c/file-io/intro/

Hubis
May 18, 2003

Boy, I wish we had one of those doomsday machines...
here's a teaser

code:
#include <stdio.h>
void main() 
    { printf("%d\n", 1["1234"]); }
outputs what and why?

TSDK
Nov 24, 2003

I got a wooden uploading this one
What's the prize?

50

EDIT: Bonus nerd points - your program is ill formed because main should be declared to return an int.

The Red Baron
Jan 10, 2005

Could/should shared_ptrs be passed/returned (but not stored, obviously) by reference to avoid the overhead of an atomic refcount update? Or are there issues with this that makes it a bad idea?

cronio
Feb 15, 2002
Drifter

The Red Baron posted:

Could/should shared_ptrs be passed/returned (but not stored, obviously) by reference to avoid the overhead of an atomic refcount update? Or are there issues with this that makes it a bad idea?

Always.

dis astranagant
Dec 14, 2006

Avenging Dentist posted:

It's exactly the same as printing to STDOUT, only you use fprintf. :confused:

I feel the need to offer an explanation for last night's megahurf. I was paying too much attention to the only example we were given, which opened the file using the open() system call, mapped the file to memory and did a bunch of random bit twiddling operations on things to get the desired output. This got me a bit confused when nothing I saw anywhere was doing anything close to that.

Hubis
May 18, 2003

Boy, I wish we had one of those doomsday machines...

The Red Baron posted:

Could/should shared_ptrs be passed/returned (but not stored, obviously) by reference to avoid the overhead of an atomic refcount update? Or are there issues with this that makes it a bad idea?

No that's a pretty good idea and I reccomend it.

Hubis
May 18, 2003

Boy, I wish we had one of those doomsday machines...

TSDK posted:

What's the prize?

50

EDIT: Bonus nerd points - your program is ill formed because main should be declared to return an int.

The prize is the knowledge of a job well done and the feeling of superiority that comes with knowing a vast array of C/C++ esoterica.

Janitor Prime
Jan 22, 2004

PC LOAD LETTER

What da fuck does that mean

Fun Shoe

Hubis posted:

here's a teaser

code:
#include <stdio.h>
void main() 
    { printf("%d\n", 1["1234"]); }
outputs what and why?

Ok wtf is 1["1234"] supposed to mean? Things like this really piss me off about C++. I know you can use the [] operator to move positions in memory. What I don't know is how "1234" is a valid offset. I guess you could use it's memory address as the value, but then how can you know where the compiler will place it? The other thing that bugs me is that 1 is a constant, so 1[] doesn't really make sense to me.

Please help my plebeian brain :(

Adhemar
Jan 21, 2004

Kellner, da ist ein scheussliches Biest in meiner Suppe.

Hubis posted:

The prize is the knowledge of a job well done and the feeling of superiority that comes with knowing a vast array of C/C++ esoterica.

He left out the "why" part though, which is what I'm more interested in.

ShoulderDaemon
Oct 9, 2003
support goon fund
Taco Defender

MEAT TREAT posted:

Ok wtf is 1["1234"] supposed to mean? Things like this really piss me off about C++. I know you can use the [] operator to move positions in memory. What I don't know is how "1234" is a valid offset. I guess you could use it's memory address as the value, but then how can you know where the compiler will place it? The other thing that bugs me is that 1 is a constant, so 1[] doesn't really make sense to me.

Please help my plebeian brain :(

1["1234"] is the same as *(1+"1234") is the same as *("1234"+1) is the same as "1234"[1] is the same as '2' is the same as 50.

That Turkey Story
Mar 30, 2003

You're all wrong. The correct answer is that it outputs the value of '2' cast to an integer. You can't make an assumption about the character set! Owned.

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh
Real men use EBCDIC, so the answer is clearly 242. :c00l:

Hubis
May 18, 2003

Boy, I wish we had one of those doomsday machines...

That Turkey Story posted:

You're all wrong. The correct answer is that it outputs the value of '2' cast to an integer. You can't make an assumption about the character set! Owned.

:drat:

UberJumper
May 20, 2007
woop
Kind of a random question. Anyways at my work i am now supposed to write a new application that connects to an ESRI geodatabase and it takes in metadata in XML. Geodatabase and everything is fine. The main issue is the XML metadata.

Theres going to be alot of different metadata types, corresponding to the different inputs they each take in. Since they want the system to be very modular. So they can add new metadata types, on the fly without recompiling and deploying a new application.

Now since alot of the fields in the metadata are going to be added to the tables in the database, what would be the best way to map those fields to specific columns in the table? I've looked at stuff like XML Binding, which seems very neat, but that requires it to be recompiled. I also looked at XSD/DTD schemes. But they seem more or less for validation and transformation of the XML.

Would it be possible to validate against the XML using XSD or DTD? In those schemes, have a variable declared indicating what fields they would be mapped to?

Now heres the next big thing... i have to use MSXML... i cant use tinyXML nor can i use Xerces. This is more or less where the issues come in, since MSXML seems rather limited. Any ideas?

RustyTrombone
Oct 23, 2007

by zen death robot
Would anyone be able to tell me how to end a program using code? Like if the user types "0" then the program closes itself? Thanks! :buddy:

edit: Thanks dentist!

RustyTrombone fucked around with this message at 05:45 on Oct 4, 2008

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh
http://wwwcgi.rdg.ac.uk:8081/cgi-bin/cgiwrap/wsi14/poplog/man/2/exit

ndb
Aug 25, 2005

This is sort of C++ and 80x86 assembly together, but I'll include it here.

I have to pass a string of characters from cin into an assembly procedure.

Out of ease of use mostly, would using std::string or using c-style strings be easier? Would I even have any difficulty if I used just a normal string?

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Clock Explosion posted:

This is sort of C++ and 80x86 assembly together, but I'll include it here.

I have to pass a string of characters from cin into an assembly procedure.

Out of ease of use mostly, would using std::string or using c-style strings be easier? Would I even have any difficulty if I used just a normal string?

If you're already using C++, then unless you're reading fixed-length records I can't see a good reason not to use std::string here. Your assembly procedure will probably expect a char* and an int, but you can get those from a std::string without any trouble, and it'll save you from writing a lot of error-prone code.

I don't know what you mean by "normal string" in contrast with both "c-style strings" and "std::string".

ndb
Aug 25, 2005

rjmccall posted:

If you're already using C++, then unless you're reading fixed-length records I can't see a good reason not to use std::string here. Your assembly procedure will probably expect a char* and an int, but you can get those from a std::string without any trouble, and it'll save you from writing a lot of error-prone code.

I don't know what you mean by "normal string" in contrast with both "c-style strings" and "std::string".

By normal string, I mean std::string.

The string that the user inputs is fixed-length, actually. I probably should have mentioned that.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Clock Explosion posted:

The string that the user inputs is fixed-length, actually. I probably should have mentioned that.

So this isn't so much a "user" as a file format? If it's really a user, you probably don't want to assume fixed-length records.

I don't know the best way to read fixed-length records from an istream; I've never had to do it.

ndb
Aug 25, 2005

rjmccall posted:

So this isn't so much a "user" as a file format? If it's really a user, you probably don't want to assume fixed-length records.

I don't know the best way to read fixed-length records from an istream; I've never had to do it.

Maybe I'm just getting the fixed-length records part wrong or confused (which happens with me a lot, unfortunately), but essentially the user types in 8 hexadecimal digits. That's it. The string is validated anyways, so there will be 8 hexadecimal digits that reach the ASM procedure.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Clock Explosion posted:

Maybe I'm just getting the fixed-length records part wrong or confused (which happens with me a lot, unfortunately), but essentially the user types in 8 hexadecimal digits. That's it. The string is validated anyways, so there will be 8 hexadecimal digits that reach the ASM procedure.

Okay. When people say fixed-length records, they generally mean some sort of data layout scheme where every record is exactly n bytes long, which lets you jump freely around the input to the record with a particular index. Generally, when dealing with fixed-length records, it's sometimes nicer to use the lower-level APIs. Since that's not really what you're talking about, I'd just use a std::string.

ndb
Aug 25, 2005

rjmccall posted:

Okay. When people say fixed-length records, they generally mean some sort of data layout scheme where every record is exactly n bytes long, which lets you jump freely around the input to the record with a particular index. Generally, when dealing with fixed-length records, it's sometimes nicer to use the lower-level APIs. Since that's not really what you're talking about, I'd just use a std::string.

Ahh, that's informative. Thank you. :)

DontMockMySmock
Aug 9, 2008

I got this title for the dumbest fucking possible take on sea shanties. Specifically, I derailed the meme thread because sailors in the 18th century weren't woke enough for me, and you shouldn't sing sea shanties. In fact, don't have any fun ever.
Alright, so I learned a little C a few years ago, but I'm mostly used to simpler languages. Yet, it has come time in my job that I need to code some C. I have looked around at various tutorials on the internet, but they have all been really wordy and hard to understand, or didn't contain the right information. Here's the deal.

I never really had any experience with arrays and binary I/O and such with the little C that I learned. What I need to accomplish is: to read a N by N by K 3-dimensional array of float data contained in a binary file, and for a particular value of the first two dimensions, copy the data along the third dimension to a 1-dimensional array of size K.

I *think* I know how to copy the binary file to an array of size (N*N*K), but then is it 1-dimensional? How do I convert it to a 3D array? Also, I'm not entirely sure on the syntax of fread/fwrite anyway, and if anyone could explain that to me I would appreciate it.

I would like to do this with the smallest runtime possible, by the way, as the reason I am using C at all is because it is faster than the other language I had been using. I thought of incrementing a pointer by N*N K times and storing the values one by one, kind of brute-force, but it is probably too time-inefficient. Or maybe it's not, do you all know?

Thanks.

emf
Aug 1, 2002



ehnus posted:

That's correct because the concept of vector immediates generally doesn't exist. You'll need to splat that value across a vector variable before you can use it
Another vectorization question. I made some simple proof-of-concept programs to play with vectorization, but with confusing results.

I'm working on a Q6600 Core2 Quad processor running AMD64 Debian stable. The system I'm interested in involves performing multiple operations on large arrays of double-precision floats. As a proof of concept I initialize two arrays (A and B) of 1024 double floats with random numbers, then perform a large number of iterations of A[n]=0.5*(A[n]+B[n]). I then sum the result and display the sum to prevent the compiler from optimizing . The three test programs have the strategies:
1: The elements are put into an array of 1024 elements. The computation is done one element at a time by iterating the array. This is the baseline.
2: The elements are put into an array of 256 4-element vectors. The computation is done one vector at a time by iterating the array.
3: The elements are put into one 1024-element vector. The computation is done on the entire vector in one statement.

With -O3, the first two programs complete in the same amount of time (~20s), whereas the third completes in a quarter of that (~5s). I would like to just use the last method, but the problem I'm working on has millions of elements. Since I can't multiply a vector times a constant, I would need to make ~7 vectors of equal size just to hold constants I need for the calculation. There must be some vector size which is the optimal minimum, right?

ehnus
Apr 16, 2003

Now you're thinking with portals!
I didn't realize you were talking about compiler autovectorization. I dunno, I find compiler autovectorization to be questionable at best and completely useless at worst.

You'd want to break them into what fits into a single SIMD register, in this case two doubles fit into a single XMM (128-bit wide) register. Vectorization works best also when you don't read and write to the same area in memory because then you can leverage compiler niceties like restricted pointers. Help the compiler by doing as little per statement as you need to when vectorizing.

For an averaging function below, I would step through the array two at a time, like this:

code:
// Assumes out, a, and b all point to different arrays
void average(__m128d* restrict out, const __m128d * restrict a, const __m128d* restrict b, int n)
{
    const __m128d half = _mm_set1_pd(0.5);

    for (int i = 0; i < n; ++i)
    {
        const __m128d a0 = a[i];
        const __m128d b0 = b[i];
        const __m128d sum = _mm_add_pd(a0, b0);
        const __m128d avg = _mm_mul_pd(half, sum);
        out[i] = avg;
    }
}

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

DontMockMySmock posted:

I *think* I know how to copy the binary file to an array of size (N*N*K), but then is it 1-dimensional? How do I convert it to a 3D array? Also, I'm not entirely sure on the syntax of fread/fwrite anyway, and if anyone could explain that to me I would appreciate it.

I'm assuming that N and K can grow large. Your program should be able to extract the data with a minimum of reads and writes, but that's contingent on some other constaints:
  • Are N and K global constants, or are they only constants on a per-file basis?
  • Does this binary file solely contain the matrix data? If not, is the other data fixed in size?
  • What's the layout of the matrix? i.e. what axis is "most continguous" in the file? For example, if I had a 3x3x2 matrix (((1 2) (3 4) (5 6)) ((7 8) (9 10) (11 12)) ((13 14) (15 16) (17 18))), would that be laid out as (1 2 3 4 5 6...), or as (1 2 7 8 13 14 ...), or (1 3 5 7 9 11 ..., or....?
  • Do you know the physical representation of numbers? Are they native-ordered IEEE floats or doubles? If not, are they at least fixed-size?

JoeNotCharles
Mar 3, 2005

Yet beyond each tree there are only more trees.
Argh, binary shifting! Pitfalls!

code:
unsigned short value = 0L;
char ch = blah blah blah
value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch);
That's giving me a warning because it converts ch to a long and then truncates it to a short. If I just change that to "(unsigned short) ch", will that cause any side effects? (Like << and >> automatically extending, or something?)

oldkike
Jan 10, 2003

hey

www.pleasegimmeadollar.com

JoeNotCharles posted:

Argh, binary shifting! Pitfalls!

code:
unsigned short value = 0L;
char ch = blah blah blah
value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch);
That's giving me a warning because it converts ch to a long and then truncates it to a short. If I just change that to "(unsigned short) ch", will that cause any side effects? (Like << and >> automatically extending, or something?)

You shouldn't need to cast that at all.. I don't think that case affects the shift at all, because its adding *after* the shift.

JoeNotCharles
Mar 3, 2005

Yet beyond each tree there are only more trees.
I suppose the cast affects whether a negative value of ch is closer to the max short or the max long.

DontMockMySmock
Aug 9, 2008

I got this title for the dumbest fucking possible take on sea shanties. Specifically, I derailed the meme thread because sailors in the 18th century weren't woke enough for me, and you shouldn't sing sea shanties. In fact, don't have any fun ever.

rjmccall posted:

I'm assuming that N and K can grow large. Your program should be able to extract the data with a minimum of reads and writes, but that's contingent on some other constaints:
  • Are N and K global constants, or are they only constants on a per-file basis?
  • Does this binary file solely contain the matrix data? If not, is the other data fixed in size?
  • What's the layout of the matrix? i.e. what axis is "most continguous" in the file? For example, if I had a 3x3x2 matrix (((1 2) (3 4) (5 6)) ((7 8) (9 10) (11 12)) ((13 14) (15 16) (17 18))), would that be laid out as (1 2 3 4 5 6...), or as (1 2 7 8 13 14 ...), or (1 3 5 7 9 11 ..., or....?
  • Do you know the physical representation of numbers? Are they native-ordered IEEE floats or doubles? If not, are they at least fixed-size?
Yes they are global constants, yes the file has solely the matrix data, it is laid out so the first dimension varies first, so in your example it would be 1,2,3,4,5, etc. the way you drew it which would actually be called 2x3x3; in other words it varies x then y then z. The numbers are 8-byte floating point numbers.

The Red Baron
Jan 10, 2005

After I read Modern C++ Design, I thought it might be neat to have an implementation of the factory patterns Alexandrescu outlines, but built around Boost rather than Loki. So I whipped up some stuff using the MPL and Boost.Preprocessor and blogblogblogged the heck out of it! I'm just reinventing the wheel as usual, but I'd love some C&C on it if anyone can be bothered :shobon:

guenter
Dec 24, 2003
All I want out of life is to be a monkey of moderate intelligence who wears a suit. That's why I've decided to transfer to business school!
Speaking of factories - In the game I'm working on I'd really like to be able to build entities based on some kind of string description. I think using a factory is the obvious way to do this but it's made more complex by my using a composition/component based type system for entities. This is how i'd go about creating a ship right now:

code:
    Entity enemyShip;

    Renderable enemyShipRenderable(Mesh("Mesh/Fighter.x", device)), Material("Fighter.fx", device));
    WorldTransform enemyShipWorldTransform;
    Body enemyShipBody;
    Collideable enemyShipCollideable;
    Team enemyShipTeam("friendly")
    ShipAi enemyShipShipAi(scene_);
    ShipController enemyShipController;
    
    enemyShip.AddComponent(enemyShipRenderable);
    enemyShip.AddComponent(enemyShipBody);
    enemyShip.AddComponent(enemyShipCollideable);
    enemyShip.AddComponent(enemyShipTeam);
    enemyShip.AddComponent(enemyShipWorldTransform);
    enemyShip.AddComponent(enemyShipController);
    enemyShip.AddComponent(enemyShipShipAi);
I'd really like to have something like:

code:
    Entity enemyShip("enemyShip.ent");
My main problem seems to be getting around the fact that the constructors for all the components are very different. Some of them take a number of primitive types, some complex objects, and some "special" objects like device and scene.

It feels like maybe I could modify the builder pattern to suit my needs but I'm still not really sure how to make it generic enough such that adding new component types would be easy.

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh
You're trying to generalize waaaay too much there. Why not just, you know, make a specialized Ship class inheriting from Entity and load stuff in from a config file?

Avenging Dentist fucked around with this message at 21:20 on Oct 8, 2008

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

DontMockMySmock posted:

Yes they are global constants, yes the file has solely the matrix data, it is laid out so the first dimension varies first, so in your example it would be 1,2,3,4,5, etc. the way you drew it which would actually be called 2x3x3; in other words it varies x then y then z. The numbers are 8-byte floating point numbers.

Okay, in that case you can do this really efficiently: fopen the file, fseek to the offset (N*x+y)*K*8, fread K*8 bytes into an appropriately-sized buffer, and fclose. You probably want to disable library-level buffering on the FILE*.

Just in case you've never used fread-like APIs before: fread can return to you with an incomplete result, so you'll need to loop until you've read all K entries. Of course, if you don't need to materialize the entire K-vector at once, you can just read it in bits and pieces and process the data as it's read.

Adbot
ADBOT LOVES YOU

That Turkey Story
Mar 30, 2003

The Red Baron posted:

After I read Modern C++ Design, I thought it might be neat to have an implementation of the factory patterns Alexandrescu outlines, but built around Boost rather than Loki. So I whipped up some stuff using the MPL and Boost.Preprocessor and blogblogblogged the heck out of it! I'm just reinventing the wheel as usual, but I'd love some C&C on it if anyone can be bothered :shobon:

Pretty cool. Some suggestions -- instead of using template template parameters, I'd recommend MPL-style metaclasses and lambdas instead. This has a few benefits. For one, MPL has many more tools for manipulating and working with metaclasses than raw templates. It also means that you may then use Boost.Parameter to make your factory templates more self-documenting and allows people to specify the arguments in any order and still implicitly get all the appropriate defaults for the unspecified parameters (such as overriding the associative container but leaving the constructor parameters implicitly default, or just changing the error policy, etc.).

A less subjective decision I'm a little concerned with is that auto_ptr is used. When working with a generic factory template, I wouldn't expect this since it implies that the objects are allocated and deallocated using new and delete. In the style of C++, that may be overly restrictive, especially in the context of a factory. To be generic, I would avoid this type of assumption and instead either have a template parameter of the factory be a deleter (defaulting to use delete) and have the create function return an auto_ptr-like smart pointer but with an attached deleter, or don't add a template parameter and instead delegate all responsibility to the user entirely.

And a more stylistic suggestion, have you considered the syntax:

my_factory["bar"].create( /* construction parameters*/ )

or even:

my_factory["bar"]( /* construction parameters*/ )

I only suggest this because it more clearly separates the "bar" lookup from the constructor argument passing, and also, with these cases you can completely avoid having to do extra argument forwarding, since you can have my_factory["bar"] or my_factory["bar"].create be a reference to an internal function object directly, so the call immediately goes into a boost::function.

Finally, instead of having 2 parameters being the base type and the constructor arguments, it may be more familiar and simpler for users to use a single function parameter, using the return type as the type returned from create, and the parameter types as the constructor parameter types:

code:
// Current code
typedef factory<  
    foo  
  , std::string  
  , mpl::vector< int, float, bar >
> myfactory_t;
code:
//Potential code
typedef factory<  
    foo* ( int, float, bar )
  , std::string
> myfactory_t;
It can be scary for users to use MPL, whereas function types are probably a bit more familiar, and in this case the type fairly accurately spells out what's happening. What's interesting here is also that instead of using a base-type, you use a pointer type or a smart pointer type, etc. Internally, this also becomes the exact type used with boost::function. That covers the "problem" I was talking earlier about the deleter as well. Note that now a user can do:

code:
//Potential code
typedef factory<  
    auto_ptr< foo > ( int, float, bar )
  , std::string
> myfactory_t;
or

code:
//Potential code
typedef factory<  
    some_other_smart_pointer_with_deleter< foo > ( int, float, bar )
  , std::string
> myfactory_t;
If you really wanted to, you could make the parameter a function object type instead of a function type and use that as the mapped type in the internal associative sequence, and that would even allow the user to override how the internal function object is stored, making your template about as generic as it could be, but that's probably overstepping the needs of the common user.

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