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
Qwertycoatl
Dec 31, 2008

A MIRACLE posted:

Can someone who understands templates help me out? I'm working on an assignment that uses some of my professor's code, which is templated out. I'm trying to add a find function. Here is the code:
code:
template<typename Tkey, typename Twgt>
int cgraph<Tkey,Twgt>::find(string cname) {
    map<Tkey,int>::iterator it;
    size_t found;
    for (it=keymap.begin(); it!=keymap.end(); it++) {
        found = it->first.name.find(cname);
        if (found != string::npos) return it->second;
    }
    cout << "City containing " << cname << " not found!\n";
    exit(1);
}

C++ is dumb and doesn't know that "map<Tkey,int>::iterator" is the name of a type, rather than a member. If you change the second line to "typename map<Tkey,int>::iterator it;", it should work.

Adbot
ADBOT LOVES YOU

Qwertycoatl
Dec 31, 2008

Could it be that with the longer function, the compiler is deciding not to inline it?

(Alternatively, if just slicing off a multiply makes it fast for whatever mysterious reason, can you change the last line to "return (scale * fabsf(f) + iscale) * f;"?)

Qwertycoatl
Dec 31, 2008

nielsm posted:

If you mean re-allocate the array, remember that it might easily involve a copy of all the items from the previous location to the new.
mobby's own suggestion of having a linked list kind of structure, just making a new allocation every time, is likely to be faster, if he's working with unbounded input.
Of course, if you know for sure that no sensible input is longer than, say, 512 bytes, just allocate that and ignore anything further. Remember to not blow your buffers :)

The array method is better than it sounds. On average, you'll be copying each byte probably about once, and definitely less than twice, compared to the linked list method where you copy each byte once. There's probably not much difference between the two approaches.

(In any case, if the input is typed or from a file, both approaches will have pretty small impact compared to the time spent reading the input into the program)

Qwertycoatl
Dec 31, 2008

TasteMyHouse posted:

This will definitely be more performant but since it requires thinking in an unfamiliar arithmetical system it might be harder to think through the logic. Option one has the advantage of being dead simple -- just express in code basic elementary school arithmetic.

Do 2 if you're looking to stretch your mind, do 1 if you just want to get the job done quickly and easily.

It's not so bad really. It's pretty much exactly the same except that everywhere you write '10' you write '65536' instead.

Qwertycoatl
Dec 31, 2008

Does VS still do that thing where if you use standard library string functions it tells you to use special Microsoft ones instead?

Qwertycoatl
Dec 31, 2008

Edit: Disregard, missed a whole page

Qwertycoatl
Dec 31, 2008

Paul MaudDib posted:


First question: According to cdecl, the pointers are instantiated like this. This seems backwards, that looks like an array of pointers to roots, what I want is a pointer to an array of roots.

root (*input_roots[num_roots];
root (*output_roots)[num_roots];

Next problem, what is the correct way to access the members via the pointer? Common sense would suggest this is the correct way to do that:

linknode *next_node = (*input_roots)[i].start;

Notice that the syntax to access a member via a pointer is very similar to the syntax to declare the pointer in the first place. That's how you work out what declarations for complicated types look like.

Qwertycoatl
Dec 31, 2008

opt posted:

Edit: Printing my original set of points comes out normal, printing everything as it goes into my linked lists looks the same, it just does this crazy output when I'm reading from the linked lists and printing it out. It is always the second part of the linked list too...once again, this works perfectly on my mac, I am completely at a loss.

It's impossible to know because you didn't actually post the code, but could it be that when you print out the data at the end, the memory for it has already been freed?

Qwertycoatl
Dec 31, 2008

Ciaphas posted:

code:
      bytesRead = fread((void*)buf, sizeof(char), BUF_SIZE, temp);
      size_t bytesWrit = fwrite((void*)buf, sizeof(char), BUF_SIZE, output);

If fread doesn't give you all the bytes you asked for, you'll still write out an entire buffer, including whatever happened to be in buf before. The BUF_SIZE in your fwrite call should be bytesRead.

Qwertycoatl fucked around with this message at 22:11 on Dec 7, 2012

Qwertycoatl
Dec 31, 2008

Rothon posted:

I came across C99's addition of the static type qualifier for array declarators:


This seems kind of weird for a couple of reasons.
  1. Why was the static keyword reused for this? It doesn't seem like a particularly appropriate choice. C99 added the restrict keyword, so it's not like the new standard was limited to what already existed in C89.
  2. How is the guarantee to the compiler that an argument will have a certain number of elements useful to the compiler? What checking does the compiler have to add if static is left out? I didn't think that the compiler even had a notion of array capacity in this sense.

Not sure why they went a different route this time on whether to add a new keyword, but you can get some possible optimisations out of it. Off the top of my head:
1. It lets the compiler assume that the argument isn't NULL, so it can skip checks for that (which might be pulled in from inline functions or whatever).
2. If it knows they exist, it can load elements of the array into memory before the program asks for them (eg pulling them into a vector register, or just reordering normal instructions for better performance). Without a guarantee that the array was big enough, it'd risk a page fault.

Qwertycoatl
Dec 31, 2008

more like dICK posted:

Is C99 widespread enough that it can be safely used in a library meant for public consumption, or should I be sticking to C89? Related, what's the go-to utility library for C these days, Apache or Glib?

e: Actually I would love any links to good resources about modern C. I'm stuck in C++ land.

Microsoft's support for C99 is somewhere between patchy and nonexistent, so if you want people to compile it in visual studio then stick to C89.

Qwertycoatl
Dec 31, 2008

Dog Jones posted:

This is exactly what I'd expect. Intel's documentation says my compiler conforms to the 1998 standard, but I can't find a copy of that. My intuition says that the program I posted before is invalid, and should report an error not just a warning.

The standard is pretty forgiving about what a compiler is allowed to do with invalid programs. I believe it's required to emit a diagnostic message, which it did. Beyond that, I don't think there's any requirement that the compiler ever refuse to compile something.

In any case const more or less runs on an honour system in C++. Even if you can't do it implicitly, you can get rid of the const pretty simply:
code:
vector<int>& refint = const_cast<vector<int>&>(mine.GetMyVec());

Qwertycoatl fucked around with this message at 21:47 on Oct 6, 2013

Qwertycoatl
Dec 31, 2008

Praseodymi posted:

So I've just got back to Uni and in one class we had to clear the screen to a colour using a memcpy to set every pixel. The "obvious" way was two nested for loops:
code:
 for( int x = 0; x < screeWidth; x++){
   for( int y = 0; y < screeHeight; y++){ 
The lecturer pointed out that this would run faster the other way around, and indeed when he swapped it the fps of the program jumped from 170 to 360. He then tried to speed it up further by doing it the way I had and just running through it as one loop and incrementing i by 4 instead of doing the 4 * (x + y * screenWidth) calculation but when he demonstrated this it only ran at ~270 fps. He didn't really give an answer why on the spot but suspected it might be to do with the compiler's optimisation. Seeing as I was fairly surprised by this and that were getting points for optimisation I was hoping someone here could explain the reason to me.

It goes much faster with x on the inside because of the processor caches. When you write your pixel to memory, it doesn't go to memory immediately, it goes into the L1 (then L2) cache, which can batch up 16/128/whatever bytes of writes to send off to memory at once. This works much better if you're writing adjacent memory locations instead of jumping to locations screenWidth apart.

I'm not sure exactly what you're doing in the last part - what's i?

Qwertycoatl
Dec 31, 2008

High Protein posted:

code:
	int result4 = input << 16 >> 16; //correct

This is actually undefined - you aren't allowed to left-shift a signed integer such that anything gets put into the sign bit.

Also the right-shift (assuming the compiler did what you wanted with the left-shift) is implementation-defined. On most platforms it will do what you want but some will zero the sign bit instead of sign-extending.

Qwertycoatl
Dec 31, 2008

roomforthetuna posted:

Not to suggest it's a good idea still, you'd probably get the exact same performance, or even better, doing something less opaque and without causing warnings, like
bool x=doingstuff(); result=(result&&x);

Or just
code:
result = doingstuff() && result;

Qwertycoatl
Dec 31, 2008

durtan posted:

Still gives me five coins instead of four when I enter ".41".

Try making it print what the coins are.

And/or trace through in your head or a debugger what path the code will take with that input.

(It's a problem with your logic, rather than syntax or floating point rounding)

Qwertycoatl
Dec 31, 2008

Zaito posted:

I can obvious make a vector<Child> and have it work, but since I intend to have different flavors of Parent, I want an array which can store all of them. Is there a way to do this or do I have to find a workaround?

You can't put a Child in a vector<Parent> - when you try, all the Child parts of the object are cut off and it becomes a Parent.

What you can do, is put a pointer to a Child into a vector<Parent*>. That will then do what you want.

Qwertycoatl
Dec 31, 2008

eXXon posted:

Ok, so I'm merely retarded. Carry on.

I guess I may as well ask if it's true that there's a potentially meaningful performance difference between ++i and i++ in a for loop, if it's not optimized away at least.

If i is an integer or something, then no. If i is a C++ class with some fancy overloaded operator++, then ++i may be faster.

Qwertycoatl
Dec 31, 2008

Skuto posted:

:commissar:

Surprised GCC doesn't warn about it.

-Wmain (it's in -Wall)

Qwertycoatl
Dec 31, 2008

FateFree posted:

I'm coming from a java background so I'm having some difficulty understanding a C library. I'm trying to execute a simple SHA256 hash on a String, but I can't really understand the method signature. If someone could provide a small main method that invokes this code with a String of "hello" and maybe prints out the byte array I would be eternally grateful.

Here is the library: http://nayuki.eigenstate.org/page/fast-sha2-hashes-in-x86-assembly
Here is the source code: http://nayuki.eigenstate.org/res/fast-sha2-hashes-in-x86-assembly/sha256.c

That function just does the main computation part of SHA256. I'd expect it to be used as part of someone's implementation of a user-level hashing function, rather than something you'd call directly. (If you look at the pseudocode here, your function seems to basically be the bit inside the "for each chunk".

Qwertycoatl
Dec 31, 2008

FateFree posted:

I see maybe thats why I've been having trouble understanding. They also include a test class, maybe I can use the method at the end?

The test class is here: http://nayuki.eigenstate.org/res/fast-sha2-hashes-in-x86-assembly/sha256test.c

Yes, that looks more like it.

code:
const char * input = "Hello";
uint32_t output[8];
int i;
sha256_hash(input, strlen(input), output);
for (i = 0; i < 8; i++)
{
    printf("%08X", output[i]);
}
(it's possible I screwed up the endianness printing the output, check against something you know the hash value of)

Qwertycoatl
Dec 31, 2008

FateFree posted:

Excellent! I checked it against the hash from a java application and it matches, thank you very much. I'm now going to attempt to invoke this from a java app via JNI, so I'll probably have more questions. One quick one, I noticed a lot of method signatures that take an array, and also take the length of the array as the next argument. In java I could just pass the array and do a length check on it rather than force another argument, but I imagine because C is not managed the same thing is not possible?

That's right, if you pass an array into a function in C, the callee can't tell how long it is and must be told via a separate parameter.

I have no idea how JNI stuff works I'm afraid.

Qwertycoatl
Dec 31, 2008

FamDav posted:

are the function pointers of the form T()? in c a function of that form can take as many arguments as you would like to supply to it, whereas in c++ that is explicitly a function that takes no arguments.

otherwise, you're gonna have to cast function pointers which means undefined behavior. i would think in that case youd be seeing runtime errors, though.


It's okay to cast function pointers to other kinds of function pointers, so long as you never call the function through a pointer of the wrong type. So when you actually want to call the function, you can cast it to the correct type just before you use it:
code:
typedef void (*void_func_ptr)();
typedef void (*int_func_ptr)(int);

void my_function(int x) {}

void_func_ptr my_shitty_pointer = (void_func_ptr)my_function;
...
((int_func_ptr)my_shitty_pointer)(27);

Qwertycoatl
Dec 31, 2008

Edison was a dick posted:

I will fight anyone who forces that in their Makefiles. It makes it a pain in the arse when you want to rebuild your whole distro with a new compiler, since it always finds new warnings.

It should be easy to temporarily turn off with a local change, but I've found when it's not there, people introduce new warnings, decide they're harmless and it's not worth the effort of fixing them right now (maybe later, in the mythical time when things are quieter), until there's so much spam you don't notice the nasty warnings any more.

Qwertycoatl
Dec 31, 2008

SharePoint is the worst thing. That salary bump had better be amazing.

Qwertycoatl
Dec 31, 2008


I like the bit where they made it by taking a library in C and renaming all the foo(bar) to bar->foo()

Qwertycoatl
Dec 31, 2008

22 Eargesplitten posted:

I've found something in an enum declaration that is really confusing to me.

code:
    enum ERP_Result
    {
        rpNone = 0,
        rpOriginInside = 1,
        rpOriginOutside = 2,
        fcv_forcedword = u32(-1)
    };
I get the first three, but what's the last one? An unsigned integer can't be -1, because the range is 0-whatever. What's it doing? I presume it's some sort of "This is hosed up" thing, but I'm not sure how it even works to assign an unsigned integer to be negative, wouldn't it look at that and give up?

The name "fcv_forcedword" makes me think it's there to force the enum's underlying type to be 32 bits wide, for some reason.

Qwertycoatl
Dec 31, 2008

If at all possible, get the register definitions as a header supplied by the hardware manufacturer, instead of pasting from the PDF. It's easy to make a very confusing mistake, and also it wouldn't be unusual for the PDF to be wrong too.

However you do it, you have to be reading/writing through something volatile or the compiler might skip out accesses that it shouldn't.

I've normally seen it done something like this:
code:
#define OVL_UI_FILL_COLOR_BASE 0x018 
#define OVL_UI_FILL_COLOR_SKIP 0x20
#define OVL_UI_TOP_HADD 0x080

#define write_reg(reg, val) do { *(volatile uint32_t*)(reg) = value; } while (0)
#define write_reg_idx(reg, idx, val) do { *(volatile uint32_t*)(reg ## _BASE + idx * reg ## _SKIP) = value; } while  (0)
(with all the register address #defines off in their own file, autogenerated from some machine-readable description of the hardware supplied by the manufacturer)

Qwertycoatl
Dec 31, 2008

Spatial posted:

My preferred way of interacting with memory mapped peripherals is overlaying nested structures and using bitfields. Autocomplete works, you don't have to care about masking things, it's easy to document and makes for very readable code at the point of use.

Depending on the hardware and compiler, using bitfields can go hideously wrong - if hardware is expecting all memory accesses to be four bytes, and the compiler turns your bitfield access into a one byte write (as it's perfectly entitled to do), the hardware might ignore it or do something stupid

e: it can also trip you up if the register makes the hardware do something when you write back a bit you read, or when reading has side effects, and all the other screwy things HW designers like to do

Qwertycoatl fucked around with this message at 18:47 on Mar 7, 2019

Qwertycoatl
Dec 31, 2008

The sun doesn't curse itself you know.

Qwertycoatl
Dec 31, 2008

Spatial posted:

e: Actually no the absolute worst is bastards who make READING a register kick off some hardware action. Inevitably you will want to debug it and the debugger will constantly read it, and you won't realise it for four hours. :v:

Yeah we have a couple of fifos where you pop them by reading them, and a ton of counter registers that are clear on read

Qwertycoatl
Dec 31, 2008

qsvui posted:

Has anyone tried using Kvasir? It's supposed to be some sort of metaprogramming library for microcontroller I/O and registers. I was considering it but the last commit was over a year ago so I assume the developer just got bored and left.

It appears to be completely undocumented.

e: Oh, not completely. But "doc" just has dolor sit amet. And there's still very little information on how to use it, and I'd hate to debug it/anything using it.

Qwertycoatl fucked around with this message at 07:45 on Mar 8, 2019

Qwertycoatl
Dec 31, 2008

Kuule hain nussivan posted:

Just let me know what you need and I'll try and post it. I'm still very new to C++ so I don't really have a good idea of what's relevant to the issue.

1) The code
2) The error message. If there are a zillion error messages, the first is the most relevant.

Qwertycoatl
Dec 31, 2008

Ralith posted:

It is absolutely not the only way to avoid copying data; it's just a particularly lazy one. See e.g. the flyweight pattern I discussed a few posts ago for an alternative. Unpredictable memory layout isn't the only danger here either; you're most likely violating strict aliasing.

I don't know what HFT codebases look like, but in my field (embedded) -fno-strict-aliasing is routine

Qwertycoatl
Dec 31, 2008

Not an eclipse user but there should be space somewhere to pass in arbitrary flags, maybe in Miscellaneous?

Qwertycoatl
Dec 31, 2008

OddObserver posted:

Hmm, what are semantics for integer divide by zero at the language level?

In C, it's undefined. Also in C++ I think.

Qwertycoatl
Dec 31, 2008

darkforce898 posted:

Are there any resources that can help me implement encryption and decryption of files and communication from a client to a server?

I'm writing a program in C that will run on embedded arm devices and has a configuration file that enables and disables certain features. How do I secure the configuration so that a user cannot just change it by hand?

Right now it has a secret key in the binary that is obsfucated that I am going to combine with an API key. I know that putting the secret key in the binary isn't going to stop someone from running Ida pro, but it will stop someone from running strings on it. And then running aes256cbc on the file to read and write.

Is there a better way to do this? I don't want to reinvent the wheel. Also, is there a better resource for OpenSSL api docs than just stack overflow and the wiki?

I think the ARM Trustzone stuff is what you want to be using if you want it to be Actually Secure, but you may not have access to it on your system, and it's probably very complicated (I've never used it) and also probably needs an expert to get it right.

Qwertycoatl
Dec 31, 2008

Jeffrey of YOSPOS posted:

I'm honestly kind of surprised that floating point multiply is slower than floating point add. Being split into an exponent and mantissa seems like it should make it much easier to compute the exponent of the product than the exponent of the sum. I guess maybe it's dominated by the slowness of multiplying the mantissas? I've coded a simple hardware floating point unit (no denormalized numbers) and multiply was definitely easier to implement.

I'd naively expect a multiplier to be slower than an adder and a barrel shifter

Qwertycoatl
Dec 31, 2008

Rocko Bonaparte posted:

I'm trying to understand the Linux kernel's hashtable.h. Right up at the beginning there's some pretty crazy macros:

code:
#define DEFINE_HASHTABLE(name, bits)						\
	struct hlist_head name[1 << (bits)] =					\
			{ [0 ... ((1 << (bits)) - 1)] = HLIST_HEAD_INIT }

#define DEFINE_READ_MOSTLY_HASHTABLE(name, bits)				\
	struct hlist_head name[1 << (bits)] __read_mostly =			\
			{ [0 ... ((1 << (bits)) - 1)] = HLIST_HEAD_INIT }
The thing is that I don't even understand that syntax! Like, what the heck does putting square brackets on the left side with three dots, then assigning something to it even mean?

If it matters, my compiler doesn't seem to get it either:
code:
userspace_hashtable.h:19:7: error: expected identifier before numeric constant
   19 |    { [0 ... ((1 << (bits)) - 1)] = HLIST_HEAD_INIT }
I'm first trying to use this in a userspace version that replaces the list implementation with a userspace-compatible one. I've used that particular code before fine. I don't think it's really coming into play here, but perhaps using g++ (since I'm trying to run Catch unit tests using this userspace hashtable) is causing problems. Is this something different between C and C++?

Yes, it's C-only (and the "...." part is a GNU extension I believe). It's initialising every element in the array to HLIST_HEAD_INIT )

Adbot
ADBOT LOVES YOU

Qwertycoatl
Dec 31, 2008

nielsm posted:

I'm pretty sure there are also some architectures where accessing true globals is troublesome, and it might actually make sense for the compiler to make multiple copies of the constant data. Is that allowed, letting the same named constant have different addresses depending on where in the program you are?

It should be fine if nothing looks at the addresses

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