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
Doctor w-rw-rw-
Jun 24, 2008

more like dICK posted:

Are there any good JSON libs for C?

Jansson?

Adbot
ADBOT LOVES YOU

xgalaxy
Jan 27, 2004
i write code

more like dICK posted:

Are there any good JSON libs for C?

I've used https://github.com/json-c/json-c before and didn't mind it.
But it was for some simple hobby stuff.

covener
Jan 10, 2004

You know, for kids!

more like dICK posted:

Are there any good JSON libs for C?

I can second jansson.

Paul MaudDib
May 3, 2006

TEAM NVIDIA:
FORUM POLICE
I'm writing a program that dumps a shitload of logs for each run. Something on the order of a gig or two uncompressed.

Is there a simple way to compress that on-the-fly? I'm currently just using your basic FILE * and fprintf line printing. Is there some way I could make the underlying stream compress to gzip or something? I'm in a POSIX environment but don't have admin access, is there a way to make a FUSE-type mount point into a compressed filesystem somewhere?

Basically I want to pipe through gzip and then to disk, but with a couple different streams instead of just stdout, or something along that line.

e: looks like Zlib should fit the bill

Paul MaudDib fucked around with this message at 23:48 on Sep 16, 2013

PENETRATION TESTS
Dec 26, 2011

built upon dope and vice
One option is setting up named pipes: http://en.wikipedia.org/wiki/Named_pipe

ephphatha
Dec 18, 2009




more like dICK posted:

Are there any good JSON libs for C?

Related, what would you recommend for a C++ library? I've been using Qt's JSON functionality since almost all my C++ projects use Qt anyway, but I'm interested in decent alternatives for things that don't need a UI.

shrughes
Oct 11, 2008

(call/cc call/cc)
I haven't taken more than a cursory glance at it, but it seems like yajl has its head together reasonably well.

Sagacity
May 2, 2003
Hopefully my epitaph will be funnier than my custom title.
We currently have a large codebase. Tons of products that all use a bunch of small components. They are referenced using SVN externals. This is a bitch to maintain since all management of externals, such as upgrading to a newer version, is completely manual.

This works, but it would be much nicer to have a model similar to npm in NodeJS land where you create a "package.json" file containing your dependencies, the semantic version of said dependencies (e.g. "1.0", "1.2.*", "latest", etc). It allows you to specify whether dependency is an actual dependency or a dependency that is used during development (e.g. CppUnit). It allows you to easily update all dependencies to the latest matching semantic version as well.

Is there something like that for C/C++ that would also allow you to specify whether you'd fetch the dependency as binary or as source. Cross-platform too, of course.

Options I've considered so far:
* CMake - That's geared more towards cross-platform project setup, builds, and so on.
* Apache Ivy - Seems more related to Java, but *should* in theory also work for other languages. Seems generally scary due to verbose XML config.
* Ryppl - Seems nice, but is also completely abandoned.

TL;DR: Are there any good dependency management systems available for C/C++ that are simple to use?

Dren
Jan 5, 2001

Pillbug
The best json library for c is wjelement. https://github.com/netmail-open/wjelement. Seriously, it's the poo poo. They implemented xpath style access to json elements and support for json-schema. Check out the example here: https://github.com/netmail-open/wjelement/wiki/WJElement-Example

Dren fucked around with this message at 18:43 on Sep 17, 2013

bobua
Mar 23, 2003
I'd trade it all for just a little more.

I'm trying to play around with threading, and getting a 'program has triggered a breakpoint' that isn't very explanatory...

code:
	std::vector<std::thread> threadParts;
	for(auto img : imgParts)
	{
		threadParts.emplace_back(ProcessImage, img, 525);
	}
	for(auto& thrd : threadParts)
	{
		if(thrd.joinable()) { thrd.join(); }	//error here
	}
	return;
What's weird, is that the first time I call this function, it works(cycles through 4 image 'parts' and returns. The second time, it gets all the way down to the line marked with the error and fails on the first execution. I've set a breakpoint and confirmed(I think) that the threads exist, they seem to have processed properly, image is there, etc. This is my first real outing into threading so hopefully I'm just missing something silly.

This doesn't help me, but maybe it will help someone else explain to me what I've done wrong... When I replace the ProcessImage function with a simple function that cout's an integer, no errors. I've never had a problem with the processimage function outside of this threading example though.

bobua fucked around with this message at 03:13 on Sep 18, 2013

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!
Is there a site listing clever collection manipulation tricks with Boost or even just STL? I've recently had to do some stuff with vectors like check if there's at least one element in one that matches some rules. I would have liked to use a lambda as a predicate function, but I couldn't figure out how to make one out of a series of compound statements. I've also wanted to create a sum from a particular field of each element in a container. It gets tedious to write the for-loops, and hides what I'm trying to do when I know the goal when I'm writing all this container examination code.

Null Pointer
May 20, 2004

Oh no!

Rocko Bonaparte posted:

Is there a site listing clever collection manipulation tricks with Boost or even just STL? I've recently had to do some stuff with vectors like check if there's at least one element in one that matches some rules. I would have liked to use a lambda as a predicate function, but I couldn't figure out how to make one out of a series of compound statements. I've also wanted to create a sum from a particular field of each element in a container. It gets tedious to write the for-loops, and hides what I'm trying to do when I know the goal when I'm writing all this container examination code.
There aren't any specific sites that I can recommend. Mostly it just comes down to knowing the STL, especially <algorithm>, iterators, and how they work together.

Your first example can be done using C++11 std::any_of.

code:
bool at_least_one = std::any_of(foo.begin(), foo.end(), [](const bar& b) { return b.baz == 3; });
For the second, you can use std::accumulate from <numeric>.

code:
int sum = std::accumulate(foo.begin(), foo.end(), 0, [](int sum_so_far, const bar& b) { return sum_so_far + b.baz; });
The rest of the STL algorithms follow the same general pattern.

OneEightHundred
Feb 28, 2008

Soon, we will be unstoppable!
Another dumb aliasing question: How does it work with struct members, or is that also undefined?

i.e. if I do this:

code:
struct StructA
{
    int a;
    int b;
};

struct StructB
{
    int a;
    int b;
};

int main(int argc, const char **argv)
{
    StructA sa;
    sa.a = 1;
    sa.b = 2;

    printf("%i", reinterpret_cast<StructB*>(&sa)->a);
    return 0;
}
.... is that guaranteed to print 1, or does the fact that it's inside of incompatible structs make it undefined?

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed
Pretty much everything involving reinterpret_cast other than casting a void pointer back to its original type is undefined behavior.

Vanadium
Jan 8, 2005

I think that's specifically allowed to enable that pattern where you bunch all those structs into a union and use the first field to figure out what to cast them to.

Edit: I guess you actually have to put them into a union for that to apply.

quote:

If a standard-layout union contains two or more standard-layout structs that share a common initial sequence, and if the standard-layout union object currently contains one of these standard-layout structs, it is permitted to inspect the common initial part of any of them. Two standard-layout structs share a common initial sequence if corresponding members have layout-compatible types and either neither member is a bit-field or both are bit-fields with the same width for a sequence of one or more initial members.

Vanadium fucked around with this message at 02:58 on Sep 19, 2013

Rottbott
Jul 27, 2006
DMC
Although it's not technically portable, I've never worked on a system where it didn't work as long as you're careful with alignment. For example it's not unusual to load data by reading in raw bytes from disk and just casting to whatever structure, perhaps with a subsequent pointer patching pass.

Vanadium
Jan 8, 2005

You're just inviting the next release of clang to see what you're doing and go "that's clearly undefined so i can optimize it by deleting your code".

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

Plorkyeran posted:

Pretty much everything involving reinterpret_cast other than casting a void pointer back to its original type is undefined behavior.

That's static_cast. This is a legal use of reinterpret_cast. As for structure layouts: you cannot portably define the exact memory layout of a structure, but you can ensure your program doesn't compile if your assumptions don't hold: use static_assert with offsetof and is_same to ensure that the offset and type of the two fields is the same. Something like this:

code:
#include <stdio.h>
#include <type_traits>

struct StructA
{
    int a;
    int b;
};

struct StructB
{
    int a;
    int b;
};

static_assert(offsetof(StructA, a) == offsetof(StructB, a), "StructA::a and StructB::a have different offsets");
static_assert(std::is_same<decltype(StructA::a), decltype(StructB::a)>::value, "StructA::a and StructB::a have different types");

int main(int argc, const char **argv)
{
    StructA sa;
    sa.a = 1;
    sa.b = 2;

    printf("%i", reinterpret_cast<StructB*>(&sa)->a);
    return 0;
}
E: might want to ensure StructA and StructB are both PODs, too

hackbunny fucked around with this message at 13:32 on Sep 19, 2013

shrughes
Oct 11, 2008

(call/cc call/cc)
At least in C you know the structure layouts will be the same in common prefixes of structures. Or at least when they make appearances in unions or something.

Bonfire Lit
Jul 9, 2008

If you're one of the sinners who caused this please unfriend me now.

hackbunny posted:

E: might want to ensure StructA and StructB are both PODs, too
They don't need to be POD, just standard-layout.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

hackbunny posted:

That's static_cast. This is a legal use of reinterpret_cast.

The reinterpret_cast is legal. The access to an object whose dynamic type doesn't match the static type you're accessing it as isn't. An access to a field is simultaneously an access to the enclosing object for the purposes of this rule, or at least that's the interpretation taken by both Clang and GCC.

What exactly happens with unions is something of a point of debate, which is part of why Clang implements this so as to not miscompile obvious cases of illegal aliasing.

bobua
Mar 23, 2003
I'd trade it all for just a little more.

Not quite sure how to google this and get the exact answer...


If I have the following layout...

foo.h
---
class foo
{...

foo.cpp
---
int my_var = 3;


Is foo a static global variable? I had been assuming it was just a global that would always start out at 3 with each instance of the class, but after playing with some threading and multiple instances, it didn't quite behave that way. To be a little more specific, I was actually using a vector and was getting a vector iterator error that I tracked down to that variable, after putting it in the header file the problem went away.

edit: to be clear, the header file has no mention of my_var

bobua fucked around with this message at 02:42 on Sep 22, 2013

nielsm
Jun 1, 2009



If your my_var is not a member of the class, and is not a local variable in a function, then it's a true global. There will be a single instance of it for the entire program.

More specifically. This:

C++ code:
// foo.h
class Foo {
public:
  int do_stuff(int n);
};

// foo.cpp
#include "foo.h"

int my_var = 3;

int Foo::do_stuff(int n) {
  my_var = my_var + n;
  return my_var;
}
There is a single my_var for the entire program. If you create two objects of the Foo class you will find that they share the data. If you use these across multiple threads, you can get race conditions.


Now this:
C++ code:
// foo.h
class Foo {
  int my_var;
public:
  Foo();
  int do_stuff(int n);
};

// foo.cpp
#include "foo.h"

Foo::Foo()
: my_var(3)
{
}

int Foo::do_stuff(int n) {
  my_var = my_var + n;
  return my_var;
}
Now my_var is a member of the class. It's not static, storage for the variable is allocated as part of each Foo instance. Notice that the variable now has to be initialised in the class' constructor instead. Separate instances of the class have separate data, although if you share one instance across multiple threads you can still get race conditions since no synchronisation or locking takes place.


Lastly, this:
C++ code:
// foo.h
class Foo {
  static int my_var;
public:
  int do_stuff(int n);
};

// foo.cpp
#include "foo.h"

int Foo::my_var = 3;

int Foo::do_stuff(int n) {
  my_var = my_var + n;
  return my_var;
}
This does precisely the same as the first example, only now the variable is a static member of the class, effectively it's been namespaced. But it's still fully global, there is a single shared value between all instances.
Note how in the .cpp file the variable's declaration is prefixed with the class' name, and in the class declaration in the .h file it's declared as static.

The difference is that in the first example, the variable has absolutely zero relation to the class. It happens to be defined in the same source file that implements a function in the class, but that's not relevant. In the first example, the variable is not declared inside the class so it has no relation to it.

OneEightHundred
Feb 28, 2008

Soon, we will be unstoppable!
The real-world application was an attempt to alias handle containers with compatible members. It sounds like it can't be done though, and if I'm one annoyance away from just going to -fno-strict-aliasing given that this is quickly becoming insufferable for low-level code and most of the advantages are easier to get by just aggressively pulling things into local vars than trying to guess when the optimizer will gently caress my code.

OneEightHundred fucked around with this message at 04:13 on Sep 22, 2013

Hughlander
May 11, 2005

What's the state of Clang on win32 these days particularly when it comes to it's standard library? I understand the library isn't finished being ported yet, can I substitute out the one in Visual Studio 2012 or 2013 when it comes out to have a mostly up to date C++11 library? This is for porting something that already runs under Linux/OS X to Windows.

Vanadium
Jan 8, 2005

OneEightHundred posted:

The real-world application was an attempt to alias handle containers with compatible members. It sounds like it can't be done though, and if I'm one annoyance away from just going to -fno-strict-aliasing given that this is quickly becoming insufferable for low-level code and most of the advantages are easier to get by just aggressively pulling things into local vars than trying to guess when the optimizer will gently caress my code.

Putting them all into a union doesn't work?

bobua
Mar 23, 2003
I'd trade it all for just a little more.

nielsm posted:


The difference is that in the first example, the variable has absolutely zero relation to the class. It happens to be defined in the same source file that implements a function in the class, but that's not relevant. In the first example, the variable is not declared inside the class so it has no relation to it.

Thanks for taking the time to spell that out, it explained it all perfectly.


Separate question, is there a de-facto library for getting fancy in the windows console? I don't really know exactly what I want to do, it's just kind of random when I'm playing with things, but I was curious if there was a go-to option instead of just googling for a bit of hackery every time I want to do something more than changing the text color.

bobua fucked around with this message at 19:28 on Sep 22, 2013

OneEightHundred
Feb 28, 2008

Soon, we will be unstoppable!

Vanadium posted:

Putting them all into a union doesn't work?
Only if I have a union with every instance of that container template in it (and that still won't work in compilers that disallow non-POD types in a union). The closest thing to a workaround is always do the loads/saves with a common type that's in all of the templates, which I can do (i.e. a void reference), but that also loses type information in the debugger and it requires a lot of shunting.

Worse still, I'm pretty sure using unions to alias is also non-standard behavior that some compilers will ignore (i.e. Sun CC), it just happens to be allowed by GCC despite other statically-provable aliasing (i.e. local vars) being ignored for some reason.

Vanadium
Jan 8, 2005

9.3 p19 posted:

If a standard-layout union contains two or more standard-layout structs that share a common initial sequence, and if the standard layout union object currently contains one of these standard-layout structs, it is permitted to inspect the common initial part of any of them. Two standard-layout structs share a common initial sequence if corresponding members have layout-compatible types and either neither member is a bit-field or both are bit-fields with the same width for a sequence of one or more initial members.

Guess it doesn't help for your fancy objects. :shobon:

fritz
Jul 26, 2003

OneEightHundred posted:

non-standard behavior that some compilers will ignore (i.e. Sun CC)

Do people still willingly use sun cc?
I haven't used it in years and years but I remember it being total poo poo.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
Willingly? No.

xgalaxy
Jan 27, 2004
i write code
Supposedly VS 2013 RC added some C99 support and has additional C++ 11 support.
I still think its lovely that they aren't adding the additional C++ 11 support into 2012 edition.

OneEightHundred
Feb 28, 2008

Soon, we will be unstoppable!

fritz posted:

Do people still willingly use sun cc?
I haven't used it in years and years but I remember it being total poo poo.
I think Intel CC might ignore it to, and that's definitely used.

What they really need to do is just make may_alias standard (or make another memory model template for it like they did with std::atomic). char being the only guaranteed aliasable type is really stupid.

OneEightHundred fucked around with this message at 21:55 on Sep 22, 2013

MrMoo
Sep 14, 2000

I had to build some apps the other day on Solaris 10 SPARC with Sun CC, lol, Sunfreeware.com is no longer free.

Slurps Mad Rips
Jan 25, 2009

Bwaltow!

Hughlander posted:

What's the state of Clang on win32 these days particularly when it comes to it's standard library? I understand the library isn't finished being ported yet, can I substitute out the one in Visual Studio 2012 or 2013 when it comes out to have a mostly up to date C++11 library? This is for porting something that already runs under Linux/OS X to Windows.

They're working on a LLVM for windows installer at the moment: http://llvm.org/builds/

However it's not entirely able to use all of Microsoft's standard library (for instance you can't use any <*stream> headers).

If you're porting something to Windows from Linux/OS X, I'd recommend using the MinGW-builds 4.8.1 SEH POSIX version. It implements all of the standard, uses SEH for exception handling, and the all of the std::future stuff actually works (it currently doesn't with MinGW Win32 threads builds, or at least it didn't in 4.8.0 and I didn't see any changes related to that in 4.8.1)

I've yet to run into a compatibility issue with it when moving from clang to mingw and back, outside of perhaps libstdc++ missing one or two constructors within container classes (specifically allocator.uses.construction)

hooah
Feb 6, 2006
WTF?
I'm having some trouble setting up a struct within a class. I've asked about it on Stack Overflow here, but my problem hasn't been resolved. Does anyone here have any insight?

nielsm
Jun 1, 2009



hooah posted:

I'm having some trouble setting up a struct within a class. I've asked about it on Stack Overflow here, but my problem hasn't been resolved. Does anyone here have any insight?

Yeah that's some pretty bad code and a question not showing much effort put into solving it yourself. No wonder it's been downvoted.

You could start with writing a function that works on a vector of structures, and finds a structure in the vector where a specific field has a given value. Then explain in this thread how that function relates to your problem at hand.

hooah
Feb 6, 2006
WTF?
Well, I'm kind of groping in the dark since I'm beyond what I've learned in class so far, so bad code shouldn't be that surprising. I did try to solve it myself, but there weren't any results when I searched for the error, and sticking a semicolon in spots that seemed they might be appropriate didn't change anything.

I've done as you suggested, but it isn't going well. Here is my testing program:
code:
#include <iostream>
#include <vector>
#include <string>

using std::cin;
using std::cout;
using std::endl;
using std::vector;
using std::string;

void findname(string &name, const vector<grades> &the_grades) {
	for (auto it = the_grades.begin(); it != the_grades.end(); ++it) {
		if (*it.get_name(name) == name) {
			cout name << " " << grades[0];
		}
	}
};

struct grades
{
	string my_name;
	vector<double> values;

	grades(string name)
	{
		my_name = name;
		vector<double> values;
	}

	int grades::add_grade(int number) {
		values.push_back(number);
	}

	string grades::get_name(string name) {
		return my_name;
	}
};

int main() {
	
	grades student_1 = grades("Ben");
	student_1.add_grade(5);
	grades student_2 = grades("Erin");
	student_2.add_grade(5);

	vector<grades> grade_book = { student_1, student_2 };
	findname("Ben", grade_book);

	
}
This throws a bunch of errors, however. Here they are:
code:
main.cpp(11): error C2065: 'grades' : undeclared identifier
main.cpp(11): error C2923: 'std::vector' : 'grades' is not a valid template type argument for parameter '_Ty'
main.cpp(12): error C2065: 'grades' : undeclared identifier
main.cpp(12): error C2923: 'std::vector' : 'grades' is not a valid template type argument for parameter '_Ty'
main.cpp(12): error C2955: 'std::vector' : use of class template requires template argument list
main.cpp(13): error C2663: 'std::vector<_Ty,_Alloc>::begin' : 2 overloads have no legal conversion for 'this' pointer
main.cpp(13): error C2663: 'std::vector<_Ty,_Alloc>::end' : 2 overloads have no legal conversion for 'this' pointer
main.cpp(14): error C2228: left of '.get_name' must have class/struct/union
main.cpp(15): error C2146: syntax error : missing ';' before identifier 'name'
main.cpp(15): error C2784: 'std::basic_ostream<_Elem,_Traits> &std::operator <<(std::basic_ostream<_Elem,_Traits> &,const char *)' : could not deduce template argument for 'std::basic_ostream<_Elem,_Traits> &' from 'std::string'
I don't understand the reason for most of these errors (obviously), and for those that I do understand what the compiler is telling me
(e.g. the error with '<<', missing identifier before 'name'), I don't understand why it's complaining.

raminasi
Jan 25, 2005

a last drink with no ice
1. Don't use the "just add semicolons" approach to debugging. I totally get why new people do that - C++'s semicolon rules aren't the most intuitive - but it will get you nowhere in the long run.

2. Before you use a class or a struct, you have to declare, and possibly define, it (depending on how you're using it). Your definition of findname tries to use grades, but the compiler doesn't know about grades yet. Move the struct definition to before the function definition.

3. cout name is invalid C++ syntax. Any time you see word otherword (that I can think of) you've done something wrong. That snippet should be cout << name.

4. Function definitions don't end with a semicolon.

5. main should return something (0 in this case).

Also, the following aren't causing compilation problems, but are worth pointing out:

6. All your struct's members are public (because they're public by default, because it's a struct), but you've also provided accessors for them, which is redundant and confusing. You should either make the data members private, change the struct to a class (which would require making the member functions public), or remove the accessors.

7. When you define a member function inside a class/struct definition, you don't need to qualify it (e.g. grades::add_grade versus just add_grade).

8. grades student_1 = grades("Ben"); can be written grades student_1("Ben");.

Adbot
ADBOT LOVES YOU

hooah
Feb 6, 2006
WTF?
Thanks for your helpful reply. 3 and 4 I really should have caught myself. I removed the accessor for the struct and removed the scope operator in the member function.

Now my question is how do I access the public data members? Specifically, in the cout statement, how do I access an element in a vector within the struct?

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