Day 211: GCC/Clang build report

In order to compile Handmade Hero on Linux and OS X there are some issues that needs to be fixed. I am looking for volunteers to bring these issues to Casey's attention during the stream.

GCC and Clang seems unhappy with casting a pointer directly to a 16 or 32 bit number. "cast from pointer to smaller type 'u32' (aka 'unsigned int') loses information".

This needs to be addressed in three places:
ParseMember in simple_preprocessor.cpp
1
printf("   {%s, MetaType_%.*s, \"%.*s\", (u32)&((%.*s *)0)->%.*s},\n",


GetOrCreateDebugViewFor in handmade_debug.cpp
1
u32 HashIndex = (((u32)ID.Value[0] >> 2) + ((u32)ID.Value[1] >> 2)) % ArrayCount(DebugState->ViewHash);


CollateDebugRecords in handmade_debug.cpp
1
Region->ColorIndex = (u16)OpeningEvent→BlockName;

This issue can be solved by casting to memory_index aka size_t before casting to u32/u16.

There is some leftover copy/pasta in handmade_platform.h. "extra tokens at end of #endif directive"
1
#endif    debug_table *


There is an empty method in handmade_debug.cpp. "control reaches end of non-void function"
1
2
3
4
inline rectangle2
PlaceRectangle(layout *Layout, v2 Dim)
{
}


_snprintf_s is not supported and needs to be replaced. This will be solved once the dependency to stdio is removed which Casey hopefully will do soon.

/Kim
Yeah, I haven't found a way to compile without "-fpermissive" warnings in gcc, but as long as it compiles and runs, warnings aren't too annoying :)
Hi Kim

I was trying to compile this on a Raspberry Pi just to have a look at how it would behave and I came across the same problems :)

The other problems I came across were the thread_id which is not defined for this platform and of course the intrinsics.. But I think I'll open a new topic to discuss this once these compilation issues are solved.

Thanks
Nuno

Edited by Nuno on
All issues from my first post are still present so I'm still looking for somebody who can bring these to Casey's attention during the stream.

Any volunteers?

/Kim
Thank you for the help :)
Now we only need to get rid of _snprintf_s

/Kim
Or make Casey add _snprintf_s functions for non-MSVC platform:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#if !COMPILER_MSVC
inline int _snprintf_s(char *buffer, size_t sizeOfBuffer, size_t count, const char *format, ...)
{
  assert(count <= sizeOfBuffer);
  va_list args;
  va_start(args, format);
  int result = vsnprintf(buffer, count, format, args);
  va_end(args);
  return result;
}

#ifdef __cplusplus
template <size_t size>
inline int _snprintf_s(char (&buffer)[size], size_t count, const char *format, ...)
{
  assert(count <= size);
  va_list args;
  va_start(args, format);
  int result = vsnprintf(buffer, count, format, args);
  va_end(args);
  return result;
}
#endif

#endif

Edited by Mārtiņš Možeiko on
Yeah, that would be great :)
Casey fixed this issue in Day 220 while insisting the cast really was permitted. It's definitely permitted in C, but C++ I wasn't so sure about, so I looked it up. In C++11 §5.2.10¶4 (draft):

A pointer can be explicitly converted to any integral type large enough to hold it. The mapping function is implementation-defined.

I couldn't find anywhere in the spec that permitted a cast from a pointer to a smaller integer. Both GCC and Clang emit an error by default because the spec requires them to.

The following would be legal so long as the implementation provides uintptr_t:

1
(u32)(uintptr_t)pointer


Casting from pointer to uintptr_t is allowed, and casting from uintptr_t to u32 is always allowed. Since uintptr_t is optional, as far as I can tell it's not possible to cast a pointer to an integer in all C++ implementations.