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
MrMoo
Sep 14, 2000

Illusive gently caress Man posted:

When you assign a lambda to a c style function pointer, what's the lifetime of things it captures by value? Do they just vanish? Seems like this shouldn't even be allowed.

It's the lifetime of the lambda, I'm not sure why one would think otherwise.

Adbot
ADBOT LOVES YOU

pseudorandom name
May 6, 2007

You can't assign a lambda that captures to a function pointer.

Ciaphas
Nov 20, 2005

> BEWARE, COWARD :ovr:


A project I'm converting from Sun to Linux (SunCC to g++) uses integer math on fpos_t. Never noticed it was doing that because SunCC is okay with it (I'm guessing in SunCC it's a typedef for ULL rather than a struct). A couple questions on the thusly-pending refactor--

- fseek and ftell work on actual integers; are there any usage gotchas beyond those of 32 and 64 bit integral types? If I could just change to these and gain access to SEEK_CUR etc it would make this easier for me
- Can I do some casting shenanigans to treat fpos_t as an integer platform-independently? (guessing no)

MrMoo
Sep 14, 2000

I presume there must be some depressing history that fsetpos was more reliable than fseek?

(edit) This isn't an overly detailed warning:

quote:

On some non-UNIX systems, an fpos_t object may be a complex object and these routines may be the only way to portably reposition a text stream.

MrMoo fucked around with this message at 01:18 on Mar 1, 2016

Ciaphas
Nov 20, 2005

> BEWARE, COWARD :ovr:


MrMoo posted:

I presume there must be some depressing history that fsetpos was more reliable than fseek?

Search me. I think this code was written by a former employee who, at the time, was fresh out of college. That said it's been so long since I've dealt with C I/O that I'm at about his level of knowledge :saddowns:

MrMoo
Sep 14, 2000

More details here:

http://www.gnu.org/software/libc/manual/html_node/Portable-Positioning.html

So depends on whether you used text mode or binary mode in fopen, but any access on fpos_t is non-portable.

MrMoo fucked around with this message at 01:22 on Mar 1, 2016

Ciaphas
Nov 20, 2005

> BEWARE, COWARD :ovr:


This is purely binary data, so if I understand The Internet® and your link correctly, fgetpos/fsetpos give me approximately jack and diddly in terms of extra capability, and I should probably refactor to fseek/ftell to save my sanity, yeah?

(edit) The difference seems to only matter on systems where the file position isn't necessarily equal to the character count for text data. Are these some arcane platforms where this happens, or is this referring to Unicode data, or what? I only ever deal with ASCII or pure binary (mostly the latter) in my work so Unicode is just a word to me.

Ciaphas fucked around with this message at 01:26 on Mar 1, 2016

sarehu
Apr 20, 2007

(call/cc call/cc)
The problem is of course that long is 32 bits on some platforms, like, 32-bit platforms, and some 64-bit platforms.

You could use ftello or ftello64. But some platforms (OS X) don't have off64_t -- instead off_t is 64 bits, and then there's some Linux define that makes off_t be 64 bits too, or something like that, I forget. It's a mess.

My general solution was to forget the off_t/off64_t mess and get file offsets into an int64_t somehow, with the right sort of conditional compilation at the edges where you interact with the system API.

Edit: fpos64_t and fgetpos64, are you loving kidding me?

Anyway my advice stands.

MrMoo
Sep 14, 2000

Correct, just completely abandon fgetpos and fsetpos because they are only different on some non-detailed esoteric platforms. I presume something awesome like AS/400.

(edit) OS X apparently can provide different results for fgetpos when using fwide as per the man page:

quote:

If the stream is a wide character stream (see fwide(3)), the position
specified by the combination of offset and whence must contain the first
byte of a multibyte sequence.

https://developer.apple.com/library/prerelease/ios/documentation/System/Conceptual/ManPages_iPhoneOS/man3/fgetpos.3.html

So text most with SJIS and other awesome character sets. I found some references to IBM mainframes as they like using awesome codings.

MrMoo fucked around with this message at 01:37 on Mar 1, 2016

Ciaphas
Nov 20, 2005

> BEWARE, COWARD :ovr:


gently caress this dumb language anyway can't I go back to that C# project I was working on :mad:

Thanks, all, I'll get to work on the refactor.

sarehu
Apr 20, 2007

(call/cc call/cc)

Ciaphas posted:

(edit) The difference seems to only matter on systems where the file position isn't necessarily equal to the character count for text data. Are these some arcane platforms where this happens, or is this referring to Unicode data, or what? I only ever deal with ASCII or pure binary (mostly the latter) in my work so Unicode is just a word to me.

My imagination would be like, what if you wanted to be super portable and some system had prependable files or front-truncatable files? Then you need an abstract notion of file position, it's not really an absolute position from the front, it's all relative :2bong:

Ciaphas
Nov 20, 2005

> BEWARE, COWARD :ovr:


I think I just had a tiny stroke reading that

Luckily for us as far as portability goes after I do this port (and the remaining projects :suicide:) we as a group will never have to look at or support Sun or 32 bit platforms ever again. Far as the current problem goes I can just enmasse replace fpos_t with long, fsetpos(file, &pos) with fseek(file, pos, SEEK_SET), etc and be done with the whole sordid thing.

Ciaphas fucked around with this message at 01:47 on Mar 1, 2016

Doc Block
Apr 15, 2003
Fun Shoe

Ciaphas posted:

The difference seems to only matter on systems where the file position isn't necessarily equal to the character count for text data. Are these some arcane platforms where this happens, or is this referring to Unicode data, or what? I only ever deal with ASCII or pure binary (mostly the latter) in my work so Unicode is just a word to me.

Isn't it mostly because on Windows the C runtime translates the \r\n into just \n when reading files opened in text mode, and vice-versa when writing, because Windows uses CR+LF for newline instead of just LF?

I remember being bitten by that years ago when trying to port some code written for Linux to Windows that sloppily opened all files in text mode, regardless of whether they were text or binary.

edit: and also for mainframe operating systems and their weird character sets too, I guess.

Doc Block fucked around with this message at 04:47 on Mar 1, 2016

fritz
Jul 26, 2003

Ciaphas posted:

A project I'm converting from ... SunCC

One of the lasting shames of the 1990s.

Ciaphas
Nov 20, 2005

> BEWARE, COWARD :ovr:


fritz posted:

One of the lasting shames of the 1990s.

We're getting off of ClearCase version control while we're at it. Believe me, friend, the shame runs deep.

feedmegin
Jul 30, 2008

Doc Block posted:

Isn't it mostly because on Windows the C runtime translates the \r\n into just \n when reading files opened in text mode, and vice-versa when writing, because Windows uses CR+LF for newline instead of just LF?

I remember being bitten by that years ago when trying to port some code written for Linux to Windows that sloppily opened all files in text mode, regardless of whether they were text or binary.

edit: and also for mainframe operating systems and their weird character sets too, I guess.

For extra fun, classic (pre-OS X) MacOS used only \r and not \n. Because gotta make sure we cover all the bases, right, can't have people just stripping off any \r's and calling it good, that'd be too easy!

netcat
Apr 29, 2008

Ciaphas posted:

We're getting off of ClearCase version control while we're at it. Believe me, friend, the shame runs deep.

We moved from ClearCase to git years ago, but we still have a ton of ClearCase deep down :gonk:

Meat Beat Agent
Aug 5, 2007

felonious assault with a sproinging boner

Doc Block posted:

I remember being bitten by that years ago when trying to port some code written for Linux to Windows that sloppily opened all files in text mode, regardless of whether they were text or binary.

Windows' implementation of POSIX read(3) also distinguishes between text and binary mode, so unless you use a non-standard flag that most implementations don't define, reading ends at the first EOF character regardless of the actual size of the file.

Ciaphas
Nov 20, 2005

> BEWARE, COWARD :ovr:


I don't have rough and ready access to a compiler at home at the moment so I'll ask here before I go to work and get frustrated again. What the hell is the right syntax and placement for declaring and defining a static array in a class?

I thought yesterday that this was it, and the internet seems to think I'm right, but the compiler insists it can't find Foo::staticMethodTable and the other one:
C++ code:
// Foo.hpp
class Foo
{
private:
  static luaL_reg staticMethodTable[2]; //having to type size twice, this isn't pebkac prone at all :(
  static luaL_reg instanceMethodTable[9];
}

// Foo.cpp
luaL_reg Foo::staticMethodTable[2] = { ... }
luaL_reg Foo::instanceMethodTable[9] = { ... }
(context: originally the definition was right next to the declaration. Worked without warning in SunCC, works--with warning--in g++, and I'm trying to clean up warnings for this port effort.

(edit) Also does this change if those two luaL_reg arrays are const?

eth0.n
Jun 1, 2012

Ciaphas posted:

I don't have rough and ready access to a compiler at home at the moment so I'll ask here before I go to work and get frustrated again. What the hell is the right syntax and placement for declaring and defining a static array in a class?

I thought yesterday that this was it, and the internet seems to think I'm right, but the compiler insists it can't find Foo::staticMethodTable and the other one:
C++ code:
...
(context: originally the definition was right next to the declaration. Worked without warning in SunCC, works--with warning--in g++, and I'm trying to clean up warnings for this port effort.

(edit) Also does this change if those two luaL_reg arrays are const?

I assume your actual code has the correct semicolons (after class Foo's closing brace, and after the initializers).

What version of g++? This works for me without warning with -Wall -Wextra -pedantic -std=c++98, in g++ version 4.8.4:

C++ code:
#include <iostream>

class foo
{
public:
  static int bar[2];
};

int foo::bar[] = {1, 2};

int main()
{
  std::cout << foo::bar[0] << " " << foo::bar[1] << std::endl;
}
Note that size in the initializer isn't needed (works with or without).

GeneralZod
May 28, 2003

Kneel before Zod!
Grimey Drawer

Ciaphas posted:

I don't have rough and ready access to a compiler at home at the moment so I'll ask here before I go to work and get frustrated again. What the hell is the right syntax and placement for declaring and defining a static array in a class?

I thought yesterday that this was it, and the internet seems to think I'm right, but the compiler insists it can't find Foo::staticMethodTable and the other one:
C++ code:
// Foo.hpp
class Foo
{
private:
  static luaL_reg staticMethodTable[2]; //having to type size twice, this isn't pebkac prone at all :(
  static luaL_reg instanceMethodTable[9];
}

// Foo.cpp
luaL_reg Foo::staticMethodTable[2] = { ... }
luaL_reg Foo::instanceMethodTable[9] = { ... }
(context: originally the definition was right next to the declaration. Worked without warning in SunCC, works--with warning--in g++, and I'm trying to clean up warnings for this port effort.

(edit) Also does this change if those two luaL_reg arrays are const?

Since they are both static and private, you might also consider taking them out of the class and putting them into an unnamed namespace in Foo.cpp.

Ciaphas
Nov 20, 2005

> BEWARE, COWARD :ovr:


It turns out that I was being an inattentive idiot yesterday and didn't see that those arrays were, in fact, outside of the class and in an extern "C" block at the bottom.

C++ code:
class Foo
{
private:
   Foo();
// somewhere in here I didn't notice a }; extern "C" {

   static luaL_reg blahblabhlahb[9];
}
Sorry about that, you two :(

What it means for something to be static and declared in a header file--even in a sentinel--is a total unknown to me, though it sounds stupid, so I just moved the drat things into an extern "C" block at the top of the cpp file and called it good.

(ed) I'm guessing a static variable in a header file mean each source file that included that CPP would get its own copy of the variable--but since it was in a sentinel, only ONE source file would get it, and we've been lucky up to now that it was the correct one. I hate header files and old code.

Ciaphas fucked around with this message at 21:34 on Mar 4, 2016

eth0.n
Jun 1, 2012

Ciaphas posted:

It turns out that I was being an inattentive idiot yesterday and didn't see that those arrays were, in fact, outside of the class and in an extern "C" block at the bottom.

C++ code:
...

Ah, that explains the lack of semicolon then...

quote:

What it means for something to be static and declared in a header file--even in a sentinel--is a total unknown to me, though it sounds stupid, so I just moved the drat things into an extern "C" block at the top of the cpp file and called it good.

(ed) I'm guessing a static variable in a header file mean each source file that included that CPP would get its own copy of the variable--but since it was in a sentinel, only ONE source file would get it, and we've been lucky up to now that it was the correct one. I hate header files and old code.

Assuming you mean an "#ifndef X/#define X" sentinel, that doesn't mean only one source file would get it. It just means that the .h won't end up being included into the .cpp multiple times (such as if multiple headers include the same header).

Each .cpp is a translation unit (assuming normal compiling conventions), which means it's the portion of source a compiler deals with at one time, and what goes into a corresponding .o file. Each translation unit includes the headers in the .cpp, and if there's a static global in a header, that means each one will get its own copy of that object in the compiled .o. When the linker combines all the .o files into the final executable, you may well end up with redundant copies, bloating the executable (it might also optimize some away), and causing unexpected behavior if the arrays get changed in one .cpp with the expectation that the others would see the changes. A static global in a header is never the right way to do things.

The "correct" way to do a global that multiple .cpp files can reference is to declare it as extern in the header, then define it (with initializer, if applicable) in exactly one .cpp file. This way, the object gets put into exactly one .o, and there's no duplication. Note that this use of extern is unrelated to the 'extern "C"' you currently have.

If only one .cpp needs your arrays at all, then what you've done is correct (assuming the arrays are gone entirely from the .h), and what should have been done in the first place. Headers are for cross-translation-unit interfaces. The fact that it's in an extern "C" block should imply that its meant to be used by some .c file somewhere, but who knows.

Ciaphas
Nov 20, 2005

> BEWARE, COWARD :ovr:


Thanks for the clarification. I knew all that about translation units at one point, it was instantly familiar once you posted, just long forgotten. Amazing how quickly you forget things when you spend a year in another language.

(ed) I do remember kind of hating that overloaded use of the keyword 'extern' back when I was learning the language. Same for 'static', too, sort of.

Sex Bumbo
Aug 14, 2004
How do yalls break out of nested loops?
E.g.
code:
for (auto i = 0u; i < 69u; ++i) {
  for (auto j = 0u; j < 420u; ++j) {
    if (i + j == 123u) { 
      goto getOut;
    }
  }
}
getOut:;
What's an actually better way to do this? Making a function that's going to get called exactly once just to do basically the exact same thing with a return statement instead of a goto sounds catastrophically stupid. Polluting the conditionals in the loop also sounds needlessly complex.

nielsm
Jun 1, 2009



That's a good way to do it, don't change it unless you're forced to by some dumb policy.

Goto is only harmful when you use it as a replacement for block-delimited conditionals and loops.

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today
Doesn't goto also skip destructors that would otherwise be called when control leaves a given block? That could cause all kinds of trouble, especially if you use RAII much.

pseudorandom name
May 6, 2007

No.

eth0.n
Jun 1, 2012

Ralith posted:

Doesn't goto also skip destructors that would otherwise be called when control leaves a given block? That could cause all kinds of trouble, especially if you use RAII much.

No, goto is supposed to call destructors. You might be thinking of longjmp, which should be avoided.

Sex Bumbo
Aug 14, 2004
I was like 99% sure it was fine and then went to stack overflow and lost some gumption.

Klades
Sep 8, 2011

Sex Bumbo posted:

How do yalls break out of nested loops?
E.g.
code:
...
What's an actually better way to do this? Making a function that's going to get called exactly once just to do basically the exact same thing with a return statement instead of a goto sounds catastrophically stupid. Polluting the conditionals in the loop also sounds needlessly complex.

If you had to get rid of the goto I guess you could make it a lambda? Then at least you wouldn't have to have the function floating around by itself.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
There is nothing too small to break out into a separate function. Give it a meaningful name and away you go.

hackbunny
Jul 22, 2007

I haven't been on SA for years but the person who gave me my previous av as a joke felt guilty for doing so and decided to get me a non-shitty av

Ralith posted:

Doesn't goto also skip destructors that would otherwise be called when control leaves a given block? That could cause all kinds of trouble, especially if you use RAII much.

goto (and switch) can skip constructors, but that's a compilation error. Nothing can skip destructors! that would seriously compromise the integrity of a program

b0lt
Apr 29, 2005

hackbunny posted:

goto (and switch) can skip constructors, but that's a compilation error. Nothing can skip destructors! that would seriously compromise the integrity of a program

longjmp and exit skip local destructors, abort and quick_exit skip global ones

hackbunny
Jul 22, 2007

I haven't been on SA for years but the person who gave me my previous av as a joke felt guilty for doing so and decided to get me a non-shitty av
I should have added an asterisk to that "nothing". Placement new is another easy way to skip destructors (I don't recommend using placement new, like ever)

Sex Bumbo
Aug 14, 2004

Jabor posted:

There is nothing too small to break out into a separate function. Give it a meaningful name and away you go.

If it's bad form to goto out of a nested loop, why is it not bad form to return out of it in the same way?

Jabor
Jul 16, 2010

#1 Loser at SpaceChem

Sex Bumbo posted:

If it's bad form to goto out of a nested loop, why is it not bad form to return out of it in the same way?

Mainly because feeling the need to jump out of a highly-nested loop while remaining in the same function usually indicates that the function is too busy and should be broken down into smaller, more digestible parts anyway. Alternatively, it could mean that you're doing error-prone manual cleanup of resources instead of doing it properly.

The goto itself is not necessarily "bad form", but it does indicate that something smelly is going on.

sarehu
Apr 20, 2007

(call/cc call/cc)
If C didn't have break or continue statements, would uses of goto replacing them also indicate that something smelly is going on?

Hubis
May 18, 2003

Boy, I wish we had one of those doomsday machines...
I'd use a bool flag and "if (bBailout) break;" checks at the end of each loop, myself, but it depends on the code.

Adbot
ADBOT LOVES YOU

Hubis
May 18, 2003

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

sarehu posted:

If C didn't have break or continue statements, would uses of goto replacing them also indicate that something smelly is going on?

or exceptions.

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