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
Xarn
Jun 26, 2015

xgalaxy posted:

I don't quite follow Sutter's argument that Rust requires annotations just after showing C++ code that requires annotations. Anyway, pretty neat to see this stuff actually working and it sounds like it will be in an update in Visual Studio before the end of the year.

I think his argument was that annotations should be exception, not norm.

Adbot
ADBOT LOVES YOU

nielsm
Jun 1, 2009



JawKnee posted:

Goddamn. Thank you, that is a dumb mistake.

Unless you're required to write C89 for some insane reason, take advantage of C99 (or C++) and declare your variables in the minimal scope necessary.
You're even already using // single-line comments, which indicates you're using C99 or compiling as C++.

Particularly loop indices in for loops are usually bad to have escape the loop. Example:
C++ code:
initialize_stuff();

for (int i = 0; i < num_threads; ++i) // i declared here
{
  do_stuff(i);
}

do_more_stuff(i); // compile error, i is only valid inside loop

JawKnee
Mar 24, 2007





You'll take the ride to leave this town along that yellow line
yeah, I initially was using i as the index for both loops and changed to j later. Just missed changing what the index variable was for tid, like a moron.

Sex Bumbo
Aug 14, 2004
In VC++, I don't think it's possible to include windows headers with language extensions turned off (/Za), right? Is it possible to disable specific extensions? Specifically: https://msdn.microsoft.com/en-us/library/s6s80d9f.aspx

Other compilers will complain about it, but I want VC++ to catch it too, but also be able to function when making a windows program.

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed
Don't use /Za. It actually just "enables obscure compiler bugs".

Sex Bumbo
Aug 14, 2004
Oh yikes, thanks.

JawKnee
Mar 24, 2007





You'll take the ride to leave this town along that yellow line
I'm having some trouble compiling some skeleton code that was provided to me. The error message I'm getting is:

code:
make: Warning: File 'FruitTetris.o' has modification time 1916 s in the future
g++ -O3 -g -Wall -pedantic -DGL_GLEXT_PROTOTYPES -I. -I/usr/include/ -Iinclude/ -L FruitTetris.o include/InitShader.o -o FruitTetris -lGL -lglut -lGLEW -lXext -lX11 -lm
/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crt1.o: In function `_start':
/build/buildd/glibc-2.21/csu/../sysdeps/x86_64/start.S:114: undefined reference to `main'
collect2: error: ld returned 1 exit status
Makefile:48: recipe for target 'all' failed
make: *** [all] Error 1
And the provided makefile:

code:
 #! /usr/bin/make

# Generic Makefile that should work with any program you're going to compile.
# Any complaints should be directed to Honghua Li at [email]honghual@sfu.ca[/email]
#
# To compile and link your program all you have to do is run 'make' in the
#    current directory.
# To clean up object files run 'make clean_object'.
# To delete any compiled files run 'make clean'.
# Originated in 2001 by Haris Teguh
# Modified in 2114 by Honghua Li

# Including of non standard library files:
#   INCLUDEDIR is where the header files can be found
#   LIBDIR is where the library object files can be found
INCLUDEDIR=/usr/include/
LIBDIR=/usr/lib

# If you have more source files add them here 
SOURCE= FruitTetris.cpp include/InitShader.cpp

# The compiler we are using 
CC= g++

# The flags that will be used to compile the object file.
# If you want to debug your program,
# you can add '-g' on the following line
CFLAGS= -O3 -g -Wall -pedantic -DGL_GLEXT_PROTOTYPES

# The name of the final executable 
EXECUTABLE= FruitTetris

# The basic library we are using add the other libraries you want to link
# to your program here 

# Linux (default)
LDFLAGS = -lGL -lglut -lGLEW -lXext -lX11 -lm

# If you have other library files in a different directory add them here 
INCLUDEFLAG= -I. -I$(INCLUDEDIR) -Iinclude/
LIBFLAG= -L$(LIBDIR2)

# Don't touch this one if you don't know what you're doing 
OBJECT= $(SOURCE:.cpp=.o)

# Don't touch any of these either if you don't know what you're doing 
all: $(OBJECT) depend
	$(CC) $(CFLAGS) $(INCLUDEFLAG) $(LIBFLAG) $(OBJECT) -o $(EXECUTABLE) $(LDFLAGS)

depend:
	$(CC) -M $(SOURCE) > depend

$(OBJECT):
	$(CC) $(CFLAGS) $(INCLUDEFLAG) -c -o $@ $(@:.o=.cpp)

clean_object:
	rm -f $(OBJECT)

clean:
	rm -f $(OBJECT) depend $(EXECUTABLE)

include depend
I have no idea what this error is referring to, and google isn't helping me here. Anyone have an idea for what's going wrong?

fritz
Jul 26, 2003

JawKnee posted:

I'm having some trouble compiling some skeleton code that was provided to me. The error message I'm getting is:

code:
make: Warning: File 'FruitTetris.o' has modification time 1916 s in the future
g++ -O3 -g -Wall -pedantic -DGL_GLEXT_PROTOTYPES -I. -I/usr/include/ -Iinclude/ -L FruitTetris.o
include/InitShader.o -o FruitTetris -lGL -lglut -lGLEW -lXext -lX11 -lm
/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crt1.o: In function `_start':
/build/buildd/glibc-2.21/csu/../sysdeps/x86_64/start.S:114: undefined reference to `main'
collect2: error: ld returned 1 exit status
Makefile:48: recipe for target 'all' failed
make: *** [all] Error 1
I have no idea what this error is referring to, and google isn't helping me here. Anyone have an idea for what's going wrong?


You're trying to build an executable, and one of the things an executable needs is a main() function. Check that FruitTetris.cpp has such a function, if that fails then check include/InitShader.cpp, and if that fails email the people who gave you the code and tell them to give you the rest.

EDIT: the first warning:
code:
make: Warning: File 'FruitTetris.o' has modification time 1916 s in the future
means your timestamps are messed up. Do a "make clean" and then try to re-make.

JawKnee
Mar 24, 2007





You'll take the ride to leave this town along that yellow line

fritz posted:

You're trying to build an executable, and one of the things an executable needs is a main() function. Check that FruitTetris.cpp has such a function, if that fails then check include/InitShader.cpp, and if that fails email the people who gave you the code and tell them to give you the rest.

EDIT: the first warning:
code:
make: Warning: File 'FruitTetris.o' has modification time 1916 s in the future
means your timestamps are messed up. Do a "make clean" and then try to re-make.

FruitTetris.cpp does have a main() function, however InitShader.cpp did not. Adding one has not removed the issue however. Running make clean has also not removed the time stamp issue, the modification time is now further in the future:

code:
make: Warning: File 'FruitTetris.cpp' has modification time 2085 s in the future
g++ -O3 -g -Wall -pedantic -DGL_GLEXT_PROTOTYPES -I. -I/usr/include/ -Iinclude/ -c -o FruitTetris.o FruitTetris.cpp
In file included from include/Angel.h:71:0,
                 from FruitTetris.cpp:17:
include/CheckError.h:37:1: warning: void _CheckError(const char*, int) defined but not used [-Wunused-function]
 _CheckError( const char* file, int line )
 ^
g++ -O3 -g -Wall -pedantic -DGL_GLEXT_PROTOTYPES -I. -I/usr/include/ -Iinclude/ -L FruitTetris.o include/InitShader.o -o FruitTetris -lGL -lglut -lGLEW -lXext -lX11 -lm
/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crt1.o: In function `_start':
/build/buildd/glibc-2.21/csu/../sysdeps/x86_64/start.S:114: undefined reference to `main'
collect2: error: ld returned 1 exit status
Makefile:48: recipe for target 'all' failed
make: *** [all] Error 1
Guess I'm getting a hold of my professor, thanks for the suggestions though.

The Laplace Demon
Jul 23, 2009

"Oh dear! Oh dear! Heisenberg is a douche!"

JawKnee posted:

FruitTetris.cpp does have a main() function, however InitShader.cpp did not. Adding one has not removed the issue however. Running make clean has also not removed the time stamp issue, the modification time is now further in the future:

code:
make: Warning: File 'FruitTetris.cpp' has modification time 2085 s in the future
Guess I'm getting a hold of my professor, thanks for the suggestions though.

Give all your files a modification time of now-ish. Something like touch **/* in the project directory should work.

pseudorandom name
May 6, 2007

LIBDIR2 is undefined and therefore expands to the empty string, -L FruitTetris.o means "also look in the directory FruitTetris.o for shared libraries", and FruitTetris.o (and by extension the main function it contains) isn't getting linked into the final executable.

JawKnee
Mar 24, 2007





You'll take the ride to leave this town along that yellow line

pseudorandom name posted:

LIBDIR2 is undefined and therefore expands to the empty string, -L FruitTetris.o means "also look in the directory FruitTetris.o for shared libraries", and FruitTetris.o (and by extension the main function it contains) isn't getting linked into the final executable.

thank you, that appears to have solved the issue

That Turkey Story
Mar 30, 2003

Long time without posting. I have a proposal up for updating void to be an object type. It will be presented in the Kona meeting in a couple of weeks: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0146r0.html

I wrote/submitted last minute so a couple of typos snuck in.

sarehu
Apr 20, 2007

(call/cc call/cc)

That Turkey Story posted:

Long time without posting. I have a proposal up for updating void to be an object type. It will be presented in the Kona meeting in a couple of weeks: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0146r0.html

I wrote/submitted last minute so a couple of typos snuck in.

So pointer arithmetic on a void* is going to work now? Well I'm opposed.

If void is an object, sizeof(void) should be standardized to be... an even number. Just so people don't start arithmeticking buffers with it.

That Turkey Story
Mar 30, 2003

sarehu posted:

So pointer arithmetic on a void* is going to work now? Well I'm opposed.

If void is an object, sizeof(void) should be standardized to be... an even number. Just so people don't start arithmeticking buffers with it.

Good thing you're not voting ;)

Just curious why you think this is a deal breaker? Misuse of pointer arithmetic there would not be portable and it's pretty important that this is allowed, otherwise you can't use void in generic code, which is the point of the proposal. FWIW, I have support from certain clang fellows on this proposal and it's considered viable and desirable -- while we'd like to completely remove pointer to void from being treated as an "any" type regarding things like pointer convertability rules and conventions, which might relax some of those concerns, it's just not feasible at this time. The proposal intentionally does not break such existing uses.

sarehu
Apr 20, 2007

(call/cc call/cc)

That Turkey Story posted:

Good thing you're not voting ;)

Just curious why you think this is a deal breaker?

I've had mistaken pointer arithmetic on void pointers get caught by the compiler. That was useful.

When encountering the generic-code-on-void problem the solution is easy, just don't use void.

The Laplace Demon
Jul 23, 2009

"Oh dear! Oh dear! Heisenberg is a douche!"

sarehu posted:

So pointer arithmetic on a void* is going to work now? Well I'm opposed.

If void is an object, sizeof(void) should be standardized to be... an even number. Just so people don't start arithmeticking buffers with it.

Special casing void* arithmetic to be an error or for sizeof(void) to equal zero would work for me. I'd love not to write extra template specializations because of its unique semantics.

sarehu posted:

I've had mistaken pointer arithmetic on void pointers get caught by the compiler. That was useful.

When encountering the generic-code-on-void problem the solution is easy, just don't use void.

What about writing generic-code-on-invokables?

That Turkey Story
Mar 30, 2003

The Laplace Demon posted:

Special casing void* arithmetic to be an error or for sizeof(void) to equal zero would work for me.

sizeof being 0 would be nice, but that's just not feasible in the language. There is a section on this topic. I'd be in favor of a change allowing that and also allowing it for user-defined types (which would get rid of the need for silly EBO tricks in use today), but that is way out of scope of this paper and somewhat orthogonal. The language currently guarantees that objects of the same type cannot share an address. Having a size 0 and allowing objects of the same type to occupy the same address would violate this assumption and would mean that arrays no longer would be usable in the ways that they are currently usable. Very many things would break down because of such a change. As long as sizeof void is left unspecified but governed by existing C++ rules, if the day eventually comes that we get size 0 types, implementations would be able to take advantage of that with respect to void. We might even consider requiring it to be size 0 at that point, though that seems somewhat unnecessary and implementations would do it in practice anyway.

The Laplace Demon posted:

What about writing generic-code-on-invokables?

Precisely. "Don't use void" isn't really a valid option. void comes up both directly and indirectly in generic code, and even standard library types have to specialize to deal with it (this even complicates the standard itself in addition to complicating users' lives as it requires specification of those specializations). The type can't realistically be ignored.

sarehu
Apr 20, 2007

(call/cc call/cc)

That Turkey Story posted:

sizeof being 0 would be nice, but that's just not feasible in the language.

It's relatively rare that it would be an issue anyway. If it's just some struct field, whatever, it takes up a space. If it's a function parameter, a calling convention could happily skip the parameter entirely (Passing it in a C-style variable length argument list would be undefined behavior?)

That Turkey Story posted:

Precisely. "Don't use void" isn't really a valid option. void comes up both directly and indirectly in generic code, and even standard library types have to specialize to deal with it (this even complicates the standard itself in addition to complicating users' lives as it requires specification of those specializations). The type can't realistically be ignored.

Oh it certainly can be. Just accept that your generic code doesn't work on void. Users can refrain from using it. Problem solved.

High Protein
Jul 12, 2009
Some overload resolution questions:

code:
class bla
{
public:
    operator int()
    {
        return m;
    }

    template<class T>
    operator const T&()
    {
        return m;
    }

    int m;
};

void main()
{
    bla b;
    const int& i = b;
}
Whether the templated or non-templated conversion operator is chosen depends on the compiler I'm using; which is correct?

code:
class bla
{
public:
   
    void func(const int& i)
    {

    }

    template<class T>
    void func(T& boe)
    {

    }

};

void main()
{
    bla b;
    int i = 2;
    b.func(i);
}
Here the templated version is picked, so it seems adding constness is less desirable to the compiler than substituting the template?

Extra question: I've got a template class that takes a pointer-to-member. Unfortunately for non-class types, I can't use the template even if I don't actually call the function. I figured that sfinae would save me here?

code:
template<class T>
class bla
{
public:

    template<int T::*ptr>
    void func()
    {
        m.*ptr;
    }

    T m;
};

void main()
{
    struct s
    {
        int i;
    };
    
    bla<s> b;
    b.func<&s::i>();

    bla<int> b2; //error
}

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

High Protein posted:

Some overload resolution questions:

"[over.match.best posted:

p2 (excerpted)"]
[A] viable function F1 is defined to be a better function than another viable function F2 if for all arguments i, ICSi(F1) is not a worse conversion sequence than ICSi(F2), and then
for some argument j, ICSj(F1) is a better conversion sequence than ICSj(F2), or, if not that,
the context is an initialization by user-defined conversion and the standard conversion sequence from the return type of F1 to the destination type (i.e., the type of the entity being initialized) is a better conversion sequence than the standard conversion sequence from the return type of F2 to the destination type.
the context is an initialization by conversion function for direct reference binding (13.3.1.6) of a reference to function type, the return type of F1 is the same kind of reference (i.e. lvalue or rvalue) as the reference being initialized, and the return type of F2 is not, or, if not that,
F1 is not a function template specialization and F2 is a function template specialization, or, if not that,
F1 and F2 are function template specializations, and the function template for F1 is more specialized than the template for F2 according to the partial ordering rules described in 14.5.6.2.

ICS1 for a conversion operator is the conversion of the original value to the object type of the operator.

High Protein posted:

Whether the templated or non-templated conversion operator is chosen depends on the compiler I'm using; which is correct?

The non-templated conversion operator. The argument conversion sequences are the same, and a conversion sequence that binds a const int & to an int has the same rank as one that binds it to a const int &, so the first bullet that orders the functions is the fourth, which says that non-templates are better than template specializations.

High Protein posted:

Here the templated version is picked, so it seems adding constness is less desirable to the compiler than substituting the template?

Yes. Binding a const int & to an int l-value involves a qualification conversion, making it not an exact match, so the first bullet applies.

High Protein posted:

Extra question: I've got a template class that takes a pointer-to-member. Unfortunately for non-class types, I can't use the template even if I don't actually call the function. I figured that sfinae would save me here?

SFINAE only applies to very specific substitutions, like those done during overload resolution. It does not apply to template instantiation in general; the compiler will not just silently erase members from the class if their signatures don't substitute.

High Protein
Jul 12, 2009

rjmccall posted:

ICS1 for a conversion operator is the conversion of the original value to the object type of the operator.


The non-templated conversion operator. The argument conversion sequences are the same, and a conversion sequence that binds a const int & to an int has the same rank as one that binds it to a const int &, so the first bullet that orders the functions is the fourth, which says that non-templates are better than template specializations.

Thanks for the answers! However, Clang, GCC and VS2015 seem to use the templated one, while older VS versions use the value one...

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

High Protein posted:

Thanks for the answers! However, Clang, GCC and VS2015 seem to use the templated one, while older VS versions use the value one...

Then I'm probably forgetting about some rule.

Okay, yes, this one is kindof strange. [dcl.init.ref]p5 says that, when initializing an l-value reference, you try to do a direct-initialization first, which does not permit binding a const l-value reference to a temporary, meaning that the non-template operator is not considered until direct binding is known to be impossible.

Dr. Poz
Sep 8, 2003

Dr. Poz just diagnosed you with a serious case of being a pussy. Now get back out there and hit them till you can't remember your kid's name.

Pillbug
I'm a working dev who did C++ in school but hasn't gone back for close to 10 years. A friend asked me for help with a school assignment and even though I've helped him on the concepts, our implementation has an issue with deadlocks. Is homework chat acceptable here? I know that the solution is something obvious we've missed.

Xarn
Jun 26, 2015
Well, it doesn't seem to be worth its own thread

Dr. Poz
Sep 8, 2003

Dr. Poz just diagnosed you with a serious case of being a pussy. Now get back out there and hit them till you can't remember your kid's name.

Pillbug
Ok cool. Here is a link to the code. Sorry for it just being a bunch of functions + a main but my friend just started grasping C and I thought it was a bit much to throw OOP at him in the middle of this assignement. I've looked at the Wikipedia page regarding the problem and the solution and this bit from the final example stood out:

quote:

This example, as written, requires that UINT_MAX + 1 is evenly divisible by BUFFER_SIZE; if it is not evenly divisible, [Count % BUFFER_SIZE] produces the wrong buffer index after Count wraps past UINT_MAX back to zero. An alternate solution without this restriction would employ two additional Idx variables to track the current buffer index for the head (producer) and tail (consumer). These Idx variables would be used in place of [Count % BUFFER_SIZE], and each of them would have to be incremented at the same time as the respective Count variable is incremented, as follows: Idx = (Idx + 1) % BUFFER_SIZE.

In an earlier version I had tracked the values of the head/tail of the queue independently from the index used to access it and think maybe I should return to that. Basically I would increment head/tail and never mod them, reserving that solely for situations where I needed to access the queue or log an action.

nielsm
Jun 1, 2009



Dr. Poz posted:

Ok cool. Here is a link to the code. Sorry for it just being a bunch of functions + a main but my friend just started grasping C and I thought it was a bit much to throw OOP at him in the middle of this assignement. I've looked at the Wikipedia page regarding the problem and the solution and this bit from the final example stood out:

The loop at line 103:
You begin by acquiring the Produce and Access semaphores. You end by releasing the Consume and Access semaphores. That doesn't match up, you don't acquire or release anything inside the loop. (If you do, it's very non-obvious.)
You should also consider not seeding the random generator all the time, that will typically make it less random rather than more.

Similar for the line 164 loop.

Dr. Poz
Sep 8, 2003

Dr. Poz just diagnosed you with a serious case of being a pussy. Now get back out there and hit them till you can't remember your kid's name.

Pillbug

nielsm posted:

The loop at line 103:
You begin by acquiring the Produce and Access semaphores. You end by releasing the Consume and Access semaphores. That doesn't match up, you don't acquire or release anything inside the loop. (If you do, it's very non-obvious.)
You should also consider not seeding the random generator all the time, that will typically make it less random rather than more.

Similar for the line 164 loop.

It is probably very non-obvious. The semaphore for Produce is given an initial threshold of 10 and consumers is given a 0. This means 10 Producers can enter the section of code to await access to the Queue. Upon finishing production, the Producer releases the Consume semaphore to grant Consumers the ability to begin consuming with the guarantee that something will be in the queue. When a Consumer enters its critical section, after consuming a value, it releases the Produce semaphore to grant Producers the ability to begin producing with the guarantee that the queue is not full.

Yes, the same affect is also sought out by using the while(); loops and I will admit to just adding a mishmash of stuff last night in a failed attempt to get it working.

Once I'm home today I'll restore the logic of RequestProduce, Request Access, Do Stuff, Release Access, Release Produce and same for Consume and give that to see if I missed it working before. Thanks for taking a look, by the way.

Edit: The random number seeding generation is done like that in a (again failed) attempt to produce more randomness. It's done in the spots its done in because I was attempting to use the PID of the child process to get some variation. Since that didn't work out like I thought it would I'll likely change it back.

Illusive Fuck Man
Jul 5, 2004
RIP John McCain feel better xoxo 💋 🙏
Taco Defender
I'm trying to remember some syntax thing and couldn't figure out a good search term to look it up. I feel like I remember a way to limit the scope of something to an if statement in a nice readable way, eg:

code:
unordered_map<string, string> map;

if (auto it = map.find("blah"); it != map.end()) {
    // do a bunch of stuff with 'it'
}
// it no longer in scope here
what's the correct way to write that?

Sex Bumbo
Aug 14, 2004

Illusive gently caress Man posted:

I'm trying to remember some syntax thing and couldn't figure out a good search term to look it up. I feel like I remember a way to limit the scope of something to an if statement in a nice readable way, eg:

code:
unordered_map<string, string> map;

if (auto it = map.find("blah"); it != map.end()) {
    // do a bunch of stuff with 'it'
}
// it no longer in scope here
what's the correct way to write that?

you could do
code:
for (auto it = map.find("blah"); it != map.end(); it = map.end()) {
//
}
?

Not something I'd do myself though

b0lt
Apr 29, 2005

Illusive gently caress Man posted:

I'm trying to remember some syntax thing and couldn't figure out a good search term to look it up. I feel like I remember a way to limit the scope of something to an if statement in a nice readable way, eg:

code:
unordered_map<string, string> map;

if (auto it = map.find("blah"); it != map.end()) {
    // do a bunch of stuff with 'it'
}
// it no longer in scope here
what's the correct way to write that?

code:
unordered_map<string, string> map;

{
    auto it = map.find("blah");
    if (it != map.end()) {
        // do a bunch of stuff with 'it'
    }
}
// it no longer in scope here
Or, if you hate the additional indentation, you can do this if you're hitler

code:
unordered_map<string, string> map;

do {
    auto it = map.find("blah");
    if (it == map.end()) break;
    // do a bunch of stuff with 'it'
} while (0);
// it no longer in scope here

Illusive Fuck Man
Jul 5, 2004
RIP John McCain feel better xoxo 💋 🙏
Taco Defender
hmm okay. I thought there was a way to do it in the if-statement, but maybe I'm thinking of some other language.

delta534
Sep 2, 2011
I want to say that this is what you want based on my understanding of scoping rules and operators.
code:
if ( (auto it = map.find("blah") )!=map.end() )
{
    //do stuff with it
}

Xerophyte
Mar 17, 2008

This space intentionally left blank

delta534 posted:

I want to say that this is what you want based on my understanding of scoping rules and operators.
code:
if ( (auto it = map.find("blah") )!=map.end() )
{
    //do stuff with it
}

That's not valid, though. The predicate for an if-statement can be an expression that's convertible to bool or a "declaration of a single non-array variable with a brace-or-equals initializer." The declaration is not in itself an expression and can't be used as one.

To limit the scope of something, use a scope block. If that's aesthetically unacceptable, don't limit the scope of the something. Avoid clever solutions like using a lambda wrapper for map::find that returns nullptr to indicate not found, even though you can, because that's the sort of thing that makes the people who maintain your code later want to murder you.

[E:] Speaking of clever things that will make my coworkers want to murder me, holy crap we're getting folds. I should keep up with the C++17 stuff more...

Xerophyte fucked around with this message at 01:32 on Oct 8, 2015

VikingofRock
Aug 24, 2008




Xerophyte posted:

That's not valid, though. The predicate for an if-statement can be an expression that's convertible to bool or a "declaration of a single non-array variable with a brace-or-equals initializer." The declaration is not in itself an expression and can't be used as one.

To limit the scope of something, use a scope block. If that's aesthetically unacceptable, don't limit the scope of the something. Avoid clever solutions like using a lambda wrapper for map::find that returns nullptr to indicate not found, even though you can, because that's the sort of thing that makes the people who maintain your code later want to murder you.

[E:] Speaking of clever things that will make my coworkers want to murder me, holy crap we're getting folds. I should keep up with the C++17 stuff more...

Hey, neat! My only problem with it is that it's not immediately obvious that this is a fold visually. I'd rather it had a more explicit syntax, for example having an std::fold(op, args...).

ChubbyThePhat
Dec 22, 2006

Who nico nico needs anyone else
Just got offered to start doing some SharePoint development for my MSP. Not sure I want to do it yet, but the salary bump is too good to not at least look into it. Any goons do SharePoint dev in C#? All the devs I've outsourced to always seem to use VB and I hate that poo poo.

Sex Bumbo
Aug 14, 2004
I know about three people that all hate it but maybe this time will be different.

Qwertycoatl
Dec 31, 2008

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

JawKnee
Mar 24, 2007





You'll take the ride to leave this town along that yellow line
So I'm having a small problem with passing an instance of a class as a function parameter.

Lets say I have a class Foo with a function called calc() like:

code:
class Foo {
public:
	Foo ( int64_t first_num) {
		i_first_num = first_num;
}

void calc() {
	printf("value: %ld\n", i_first_num);
}

private:
	int64_t i_first_num;

Foo(const Foo& obj);
Foo& operator=(const Foo& obj);
};
That I'm instantiating in main() in another file like so:

code:
Foo f(<some number, who cares>);
2nd_func::bar(&f);
where bar is in another file like so:

code:
namespace 2nd_func {
	
	namespace internal{
	
	template <typename T>
	class Task {
	public:
		Task(T* functor) {
			m_functor = functor;
		}
		
		void execute() {
			m_functor->calc(); //Running it this way results in seg-faults when trying to access the functor's member variables
		}
	private:
		T* m_functor;
	};  
	}

	template <typename T>
	extern inline
	void bar(T* functor) {
		internal::Task<T> t(functor);
		t.execute();

		//functor->calc(); //if, instead of the above 2 lines I do this, the functor functions normally		
	}
}
I'm getting seg-faults when I try and access the functor's member variables, through the parameter passed to the Task instantiated execute() function, but not when I try to access them via the bar function. I'm assuming this is because I've messed up how I'm passing the functor parameter, but I'm not entirely sure. Should I be trying to pass it differently?

e: aaand now it's working. Odd.

JawKnee fucked around with this message at 02:15 on Oct 14, 2015

Adbot
ADBOT LOVES YOU

Xarn
Jun 26, 2015
First of all, if you have access to C++11 I heartily recommend using std::function instead.

Anyway, my guess would be that since your Task<T> has naive copy constructor and assignment, you tried returning it and it outlived the original object.

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