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
ctz
Feb 6, 2003

Avenging Dentist posted:

Non-standard and fairly brittle (works in Windows and Linux):

code:
cout << "\r" << whatever << flush;

I believe the behaviour of a carriage return written to a terminal is standard according to POSIX.

And you can (must!) fix the brittleness by guaranteeing that `whatever' is of constant length. In particular, you'll get wrong output from use like:

code:
  cout << "\r" << float(1.234234) << flush;
  cout << "\r" << float(1.1) << flush;

ctz fucked around with this message at 17:46 on Apr 11, 2009

Adbot
ADBOT LOVES YOU

ctz
Feb 6, 2003

Werthog posted:

I want to be able to read layout configurations from text files, creatable by hand [...] would XML be something I want to consider?

No. XML is a poor format for human interaction. I suggest YAML: it's easy to read and write for humans or programmatically using one of the many available libraries (though to be clear, XML achieves the latter well).

It's also worth noting that YAML's infoset is usefully richer than XML's, so you wouldn't need to define your own time-stamp or cross-reference format like you must with XML.

And it's pretty. XML is butt-ugly in comparison.

ctz
Feb 6, 2003
i'm pretty sure the entrypoint must use the cdecl calling convention. the strange behaviour related to the first time you're coming to use the stack it won't be in a reasonable state (though presumably in a reasonable enough state to call GetAsyncKeyState -- using stdcall rather than cdecl).

presumably you're writing your own C runtime library from scratch? if not, you're making a serious error in your entrypoint (it should be WinMain for win32, main for console).

ctz
Feb 6, 2003

Anunnaki posted:

What is a good Windows alternative to Valgrind? The only things I've been able to find are Insure++ and Purify, both of which aren't free.

I have never come across any. Purify is not only not free; it's expensive, and has massive overhead (a test which takes 30 minutes under valgrind takes 5.5 hours under purify with comparable hardware).

Generally speaking there are far fewer quality free development tools for Windows. It's the nature of the platform.

I suggest making your program portable or perhaps using valgrind under wine.

ctz fucked around with this message at 09:31 on May 6, 2009

ctz
Feb 6, 2003
C99: Is the following statement true or false?

It is impossible to portably call the following function with integer literals, without casting, and with a non-zero first argument.

code:
void test(int count, ...)
{
  va_list args;
  va_start(args, count);
  
  while (count--)
  {
    size_t i = va_arg(args, size_t);
    printf("%zu\n", i);
  }
}
In other words, all the following uses are non-portable:

code:
test(1, 1);
test(1, 1u);
test(1, 1ul);
test(1, 1ull);
While the following are portable:

code:
{ size_t i = 1; test(1, i); }
test(1, (size_t) 1);
Right?

ctz
Feb 6, 2003

Avenging Dentist posted:

Incorrect. Variadic arguments are subject to the rules of default argument promotion (float -> double, and smaller integer types converted up to int or unsigned int).

I don't think default argument promotion applies here: the interesting arguments are decimal integer literals which are always at least ints (6.4.4.1).

Avenging Dentist posted:

EDIT: note that this means integral types larger than int retain their size and require knowledge of their types to be dereferenced. See §7.15 of the ISO standard.

Exactly! In the examples:

code:
test(1, 1);
test(1, 1u);
test(1, 1ul);
test(1, 1ull);
The types of the second argument are int, unsigned int, unsigned long and unsigned long long. None of these are guaranteed "compatible types" with size_t, and as 7.15 says:

quote:

If there is no actual next argument, or if type is not compatible with the type of the actual next argument (as promoted according to the default argument promotions), the behavior is undefined, except for the following cases:
* one type is a signed integer type, the other type is the corresponding unsigned integer type, and the value is representable in both types;
* one type is pointer to void and the other is a pointer to a character type.
(emphasis mine)

ctz
Feb 6, 2003
Does anyone use a commercial static analysis tool day-to-day? If so, what tool do you use? How do you find it? How could it be improved? What bugs or potential bugs is it good and bad at pointing out?

ctz
Feb 6, 2003

Ledneh posted:

Can I expect this behavior to be consistent across compilers, or will some compilers zero out those bits?
Your read of i32 after writing i16 is, strictly speaking, undefined. It could yield any value, trash unrelated storage or crash. Don't do that then.

The actual behaviour you'll see will be much more dependent on architecture than compiler.

ctz
Feb 6, 2003

floWenoL posted:

Shouldn't there be some #pragmas in the boost headers that add the boost lib directories to the right place?

No, those pragmas only name the libraries which need to be linked in. This doesn't help with library search.

'HondaCivet' -- if you did build boost you didn't build it for the right flavour. 'mt-gd' denotes a debug build against the multi-threaded debug DLL CRT. See: http://www.boost.org/doc/libs/1_39_0/more/getting_started/windows.html#library-naming

ctz
Feb 6, 2003

litghost posted:

What does it do?

The only thing I'd expect it to do is emit a diagnostic about 'mF' at compilation time.

ctz
Feb 6, 2003

Avenging Dentist posted:

Also keep in mind that intN_t and uintN_t are not mandated by the standard.

They are if you have integral types which can fit the requirements, which most implementations will.

ctz
Feb 6, 2003

Avenging Dentist posted:

For all I know, the code you posted could make demons fly out of my nose, and I just don't think it's in my best interests to risk testing it. :ohdear:

You've misread the quoted section. In UraniumAnchor's silly example _________________F is not a global name, and the global name Foo::_________________F does not start with the reserved prefixes.

ctz
Feb 6, 2003

Avenging Dentist posted:

Each name that contains a double underscore

:doh:

ctz
Feb 6, 2003

Rahu posted:

The problem is that I get an error on the line "int result = htoi(input);" and I'm not sure why its happening.

In C89 all variable declarations must be at the start of a block, before any statements. In C99 you may have declarations interspersed with statements.

cl is a C89 compiler. GCC is a C99 compiler. Hence the difference.

ctz
Feb 6, 2003

Veritron posted:

i know there's some kind of tacit agreement to ignore you going on here, but you are like some kind of reverse genius

please don't question my algorithms

ctz
Feb 6, 2003

Dijkstracula posted:

hint: you're not gonna be able to get substrings out of your big string in constant time, unless you're okay with overwriting your original array with '\0's.

Mr Dentist already went over this. NUL-terminated strings are fundamentally flawed anyway, you wouldn't choose to use them.

ctz
Feb 6, 2003

ultra-inquisitor posted:

Is there a way to change the instruction pointer like that in C or should you just use inline asm?

longjmp does this, and is standard C. However the layout and contents of struct jmp_buf is implementation defined, so it's just a bad way of avoiding inline asm.

ctz
Feb 6, 2003

Plorkyeran posted:

Why would you use longjmp/inline asm instead of just generating machine code which follows the appropriate calling convention then setting a function pointer to the appropriate address and calling it?

Well, quite. The question was more general than this.

ctz
Feb 6, 2003

JonM1827 posted:

I have a basic struct, and I create a vector of that struct. I am wondering if it is possible to overload the [] operator so I can have the value within the brackets be one of the variables within the struct.

It sounds like your asking for an associative container like std::map or std::multimap (depending on whether values for 'i1' are usefully treated as unique, or not).

ctz
Feb 6, 2003
Use of std::map::operator[] requires that the value type is default constructible. This is because if you ask for a member which does not exist it inserts and returns a new default-constructed member.

ctz fucked around with this message at 15:33 on Nov 24, 2009

ctz
Feb 6, 2003

king_kilr posted:

What on earth does, error: expected ‘;’ before ‘(’ token mean.

impossible to tell from that small snippet. post the whole pre-processed translation unit.

ctz
Feb 6, 2003

Subway Ninja posted:


your program boils down to std::cin >> "";. This has two problems:

a) istream::operator>>(char *) reads some number of characters and writes them to the supplied address. The number of characters can be given an upper bound, but you didn't so this would be a buffer overrun. In any case, its a lovely misfeature akin to gets(3) -- don't use it.

b) "" is a string literal, a pointer to a single NUL. Writing to the address if a string literal is undefined behaviour, on modern implementations your program will segfault at this point.

in other words, use std::string already.

ctz
Feb 6, 2003
Declare your enum using a construction like this, in some header:

code:
#define FOO_ENUM_MEMBERS \
  ENUM_DECL(Apple) \
  ENUM_DECL(Pear) \
  ENUM_DECL(Orange) \
  ENUM_DECL(Blackcurrent) \
  ENUM_DECL(Pumpkin)

enum Foo
{
#define ENUM_DECL(nn) nn,
FOO_ENUM_MEMBERS
#undef ENUM_DECL
  Foo_MAX
}

extern const char *Foo_to_string(enum Foo e);
(If you want the enum's members to have manually assigned values, you'll probably want to have ENUM_DECL take two arguments rather than one here).

Now the implementation of Foo_to_string is:

code:
const char *Foo_to_string(enum Foo e)
{
  switch (e)
  {
#define ENUM_DECL(nn) case nn: return #nn;
FOO_ENUM_DECLS
#undef ENUM_DECL
  default: return "Unknown Foo";
  }
}

ctz
Feb 6, 2003

Zhentar posted:

2. It doesn't do dead-code removal. This will likely result in a compiled binary twice as large as compared to MSVC.

It certainly does do dead-code removal. I think you're referring to link-time optimisation (a distinct, related feature) which was only recently implemented and hasn't found its way into a stable release yet. Both have been implemented in CL for quite a while now.

ctz
Feb 6, 2003

Paniolo posted:

Does anyone know if there's a significant performance difference between using the Win32 overlapped i/o (i.e. ReadFileEx) on a single thread versus using blocking i/o on multiple worker threads? My use case is asynchronously loading game assets from disk - potentially involving simultaneous pending reads from the same archive file - if that makes any difference.

if you're worried about performance while using manual file io, you're doing it wrong. use memory mapped-files and let the kernel worry about it.

ctz
Feb 6, 2003

AbstractBadger posted:

I am having some trouble with malloc.

http://c-faq.com/ptrs/explscale.html

Aside from this, please never write sizeof(char), and prefer 'mptr[j]' to '*(mptr + j * (sizeof (char)))'.

ctz
Feb 6, 2003

clearly not a horse posted:

http://codepad.org/ag9JeJYI

At line 144, I get a compilation error. Something about the constructor of a derived class.
You provided a constructor for node. That means the compiler omitted an implementation of a default constructor for it (see paragraph 5 of class.ctor). On line 144 you rely on node having a default constructor (by omission of a suitable member initializer).

The fix you want is either to define a default constructor for node, or add a member initializer for lexicalnode's base.

ctz
Feb 6, 2003

Jose Cuervo posted:

Is there something stupid I am missing or doing?

Yes, you're using iostreams -- possibly the most poorly designed programming interfaces in the history of computing.

(Real answer: predicate your loop on readIn.good() rather than !readIn.eof(). There are more problems possible with a stream than just EOF, and their incidence isn't consistent between implementations or defined properly in the C++ standard.)

ctz
Feb 6, 2003
code:
  while((!ferror(fp)) && (!feof(fp))) {
    bufsize *= 2;
    temp = file;
    file = malloc(bufsize * sizeof(int));
    if (temp) { //avoid first iter
->    memcpy(file, temp, bufsize * sizeof(int));
      free(temp);
    }
  ...
1. Use realloc, this is what it is designed for.
2. On the second run through the loop, 'temp' points to bufsize / 2 words, but you copy bufsize words from it. It probably fails at the point it does, because it's only then that you run off pages owned by your process. But even before then, it's grossly undefined.
3. On the second run through the loop, you copy data into a possibly NULL pointer (file, returned from malloc).

ctz fucked around with this message at 15:34 on Jul 4, 2010

ctz
Feb 6, 2003
while we're being pedantics, C's char type cannot store a character. depending on encoding, a character may need up to 4 bytes (using common encodings). so how about :

'A 5 character array in C takes between 5 and 20 bytes of memory.'

ctz
Feb 6, 2003
Do you have any code or libraries which are using mmx/sse* functions without issuing emms?

ctz
Feb 6, 2003

Edison was a dick posted:

The compiler should catch this anyway, but that's 4 characters worth.

5.

ctz
Feb 6, 2003

rjmccall posted:

Applying the dereference operator (*) to null is undefined behavior only if the subsequent lvalue is actually accessed, i.e. read, written from, or called (or bound to a reference, naturally).

This is absolutely wrong with respect to C. I'm not sure about the exact semantics of C++ -- which puts me on par with the WG.

ctz fucked around with this message at 18:24 on Apr 21, 2011

ctz
Feb 6, 2003

nielsm posted:

Microsoft probably made the right choice in COM

Elaborate troll detected.

ctz
Feb 6, 2003
^ is bitwise XOR, not exponentiation. y ^ y evaluaties to 0 for all y.

C and C++ do not have exponentiation operators, instead there are functions in the standard library (pow, which is defined only for floating point numbers).

ctz
Feb 6, 2003
std::string belongs in the C++ shitheap along with iostreams, vector<bool> and most of the C string functions.

ctz
Feb 6, 2003

schnarf posted:

C++ doesn't really know anything about threads.
Careful, now. C++03 doesn't.

ctz
Feb 6, 2003

Otto Skorzeny posted:

I'm getting an error that I can't figure out (C89 code):

C++ code:
enum notice {
	NOTICE_VERSION = 0,
	NOTICE_LOGGING,
	NOTICE_WARMUP_LEFT,
	NOTICE_WARMUP_RIGHT,

};
error: 'notice' defined as wrong kind of tag

I understand (I think) that enums and structs live in the same namespace, but I did a whole-project search and I don't use notice as the name of anything else anywhere. Any idea what's up? Compiler is ARM gcc 4.1 for reference.

Look at your code once it has been preprocessed. For gcc, that's gcc -E. This should give you a huge translation unit with all the definitions in-play at the point of your error.

ctz
Feb 6, 2003

Dog Jones posted:

I tried compiling both programs with intel's c++ compiler, and the debugger now indicates the correct values. So I guess the visual c++ debugger generates incorrect debugging information, while intel's generates correct information?

That, or ICC does different register allocation such that both i values get put in the same register.

(This is assuming that the PE/COFF debugging information for a function/BB is along the lines of 'variable i is stored in register eax'.)

Adbot
ADBOT LOVES YOU

ctz
Feb 6, 2003

Coca Koala posted:

I'm really not that great at C.

The best thing to do is add threads. Multithreading is easy and is an excellent thing for beginners to tackle.

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