Visual Studio warning C4334 on assignment but not on initialization - visual-c++

Why i got warning on this code:
#include <cstdint>
int main()
{
int i = 1;
int64_t i64;
i64 = 1 << i;
}
warning C4334: '<<' : result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?)
but not on this:
#include <cstdint>
int main()
{
int i = 1;
int64_t i64 = 1 << i;
}
?
Tested on vs2013/2015.

I see the same discrepancy with vs2012. I don't think that there is a good reason for it - hopefully the warning will be emitted in both cases in a newer version of Visual C++.

MSVS 2015 Upd.2: Second case (on initialization) will trigger C4334 warning.

Related

Clang performs better than MSVC on Windows

The c++ code compiled by clang runs a lot faster than the same code compiled by MSVC. And I checked the ASM code, found out that clang automatically uses SIMD instructions for speed purposes. So I rewrite the main calculation part by using AVX Intrinsics code. Still, the program compiled by Clang gains a 10% benefit of speed.
Is it common sense that Clang performs better than MSVC on Windows? Or I missed some important optimization configurations of MSVC.
I've tested these code:
static __inline int RGBToY(unsigned char r, unsigned char g, unsigned char b) {
return (66 * r + 129 * g + 25 * b + 0x1080) >> 8;
}
void ToYRow_C(const unsigned char* src_argb0, unsigned char* dst_y, int width) {
int x;
for (x = 0; x < width; ++x) {
dst_y[0] = RGBToY(src_argb0[2], src_argb0[1], src_argb0[0]);
src_argb0 += 3;
dst_y += 1;
}
}
And the compiling flags for Clang: -O2 -mavx2, flags for MSVC: /O2 /arch:AVX2.
Processing a 2560x1440 image on a clang-compiled program costs 1.2ms, and 4.2ms for a MSVC-compiled program.

How to load 4 integer values efficiently in neon register on msvc compiler?

How do I implement below operation efficiently on msvc compiler?
uint32x4_t temp = { 1, 2, 3, 4 };
I have to load 4 different values in neon register very efficiently since I am working to optimize performance. Above statement works for android clang but fails on msvc compiler since uint32x4_t is typedef'ed to __n128.
Following is the structure of __n128:
typedef union __declspec(intrin_type) _ADVSIMD_ALIGN(8) __n128
{
unsigned __int64 n128_u64[2];
unsigned __int32 n128_u32[4];
unsigned __int16 n128_u16[8];
unsigned __int8 n128_u8[16];
__int64 n128_i64[2];
__int32 n128_i32[4];
__int16 n128_i16[8];
__int8 n128_i8[16];
float n128_f32[4];
struct
{
__n64 low64;
__n64 high64;
} DUMMYNEONSTRUCT;
} __n128;
In C99, when initializing a union with a initializer list, you can specify the particular members that are initialized, as follows:
uint32x4_t temp = { .n128_u32 = {1,2,3,4} };
However, this C99 syntax is only supported in Visual Studio 2013 and higher. Visual Studio 2012 and below do not support this feature, and thus, you can only initialize a union with a static initializer based on the first entry (n128_u64). You could come up with an initializer that fits your uint32 data into uint64. Since they are constants, it will not take any additional execution time. Looks really ugly:
uint32x4_t temp = { { 1 << 32 | 2, 3 << 32, 4 } };
If this code needs to be portable between compilers, a better option would be to create a preprocessor macro, that handles formatting of constants.

Visual C++ versus standard c++

1) I have been working with standard C++ (CodeBLocks)and starting to move to Visual C++. When creating a console application the VS builds the following:
#include "stdafx.h"
int _tmain(int argc, _TCHAR* argv[])
{
return 0;
}
This is not the standard c++ syntax but windows version.
Now, is there a way to use the standard c++ syntax in Visual Studio C++ and avoid the above
sintax so as to use the standard?
I mean, using VS C++ be able to code something standard such as:
#include "<iostream.h>"
#include <stdlib.h>
int main()
{
int month, day, year;
cout << "Hellow World" << endl;
return 0;
}
2) I get in visual c++ error by trying to include very common libraries such as
#include "<iostream.h>". Any advise much appreciated. (using VS 2013 and comparing it with previous code in WnDEv).
3) I also attemted to use this with an empty project adding:
but when I build it InteliSense cannot open source file stdafx.h, IntelliSense identifier "cout" is undefined, IntelliSense identifier "cin" is undefined. Please help. thank you
#include "stdafx.h"
#include<iostream>
#include<conio.h>
void main()
{
//clrscr();
int number, count = 0;
cout << "ENTER NUMBER TO CHECK IT IS PRIME OR NOT ";
cin >> number;
for (int a = 1; a <= number; a++)
{
if (number%a == 0)
{
count++;
}
}
if (count == 2)
{
cout << " PRIME NUMBER \n";
}
else
{
cout << " NOT A PRIME NUMBER \n";
}
//getch();
}
The inclusion of "stdafx.h" is because Visual C++ by default uses pre-compiled headers, and for that to work the first non-comment line in the source file have to be that inclusion.
For the _tmain function, it tells me you have opted to make a WIN32 console project. You can make an empty project, and add files manually as needed, and use only standard C++ features, like having the proper main function instead.

trying to learn _beginthreadex and passing parameters

copying some data I had for working boost threads, I implemented the following code below.
I get the error C:\dev\default threads_threads.cpp|18|error: invalid conversion from 'void ()(void)' to 'unsigned int (attribute((stdcall)) )(void)' [-fpermissive]|
but... the commented lines are what was recommended, and a comment explains the error I got.
it turns out _beginThreadEx is highly recommended, but poorly documented (as in tutorials) on the web
#include <iostream>
#include <process.h>
void myThread(void *data)
{
//C:\dev\default threads\_threads.cpp|6|error: invalid conversion from 'int*' to 'int' [-fpermissive]|
//int x = static_cast<int*>(data);
int *x = (int*)data;
std::cout << "Hellow World! " << x;
}
int main()
{
int x = 10;
_beginthreadex(NULL, 0, myThread, &x, 0, NULL);
while(true);
}
You have to declare x as pointer anyway:
int *x = static_cast<int*>(data);
both _beginthread and _beginthreadex are documented here: http://msdn.microsoft.com/en-us/library/kdzttdcb(v=vs.80).aspx
According to the declaration of _beginthreadex() your myThread() function should be declared like this:
unsigned __stdcall myThread(void *data);

How do I make a multi-threaded app use all the cores on Ubuntu under VMWare?

I have got a multi-threaded app that process a very large data file. Works great on Window 7, the code is all C++, uses the pthreads library for cross-platform multi-threading. When I run it under Windows on my Intel i3 - Task manager shows all four cores pegged to the limit, which is what I want. Compiled the same code using g++ Ubuntu/VMWare workstation - same number of threads are launched, but all threads are running on one core (as far as I can tell - Task Manager only shows one core busy).
I'm going to dive into the pThreads calls - perhaps I missed some default setting - but if anybody has any idea, I'd like to hear them, and I can give more info -
Update: I did setup VMWare to see all four cores and /proc/cpuinfo shows 4 cores
Update 2 - just wrote a simple app to show the problem - maybe it's VMWare only? - any Linux natives out there want to try and see if this actually loads down multiple cores? To run this on Windows you will need the pThread library - easily downloadable. And if anyone can suggest something more cpu intensive than printf- go ahead!
#ifdef _WIN32
#include "stdafx.h"
#endif
#include "stdio.h"
#include "stdlib.h"
#include "pthread.h"
void *Process(void *data)
{
long id = (long)data;
for (int i=0;i<100000;i++)
{
printf("Process %ld says Hello World\n",id);
}
return NULL;
}
#ifdef _WIN32
int _tmain(int argc, _TCHAR* argv[])
#else
int main(int argc, char* argv[])
#endif
{
int numCores = 1;
if (argc>1)
numCores = strtol(&argv[1][2],NULL,10);
pthread_t *thread_ids = (pthread_t *)malloc(numCores*sizeof(pthread_t));
for (int i=0;i<numCores;i++)
{
pthread_create(&thread_ids[i],NULL,Process,(void *)i);
}
for (int i=0;i<numCores;i++)
{
pthread_join(thread_ids[i],NULL);
}
return 0;
}
I changed your code a bit. I changed numCores = strtol(&argv[1][2], NULL, 10); to numCores = strtol(&argv[1][0], NULL, 10); to make it work under Linux by calling ./core 4 maybe you where passing something in front of the number of cores, or because type _TCHAR is 3byte per char? Not that familiar with windows.. Further more since I wasn't able to stress the CPU with only printf I also changed Process a bit.
void *Process(void *data)
{
long hdata = (long)data;
long id = (long)data;
for (int i=0;i<10000000;i++)
{
printf("Process %ld says Hello World\n",id);
for (int j = 0; j < 100000; j++)
{
hdata *= j;
hdata *= j;
hdata *= j;
hdata *= j;
hdata *= j;
hdata *= j;
hdata *= j;
hdata *= j;
hdata *= j;
hdata *= j;
hdata *= j;
...
}
}
return (void*)hdata;
}
And now when I run gcc -O2 -lpthread -std=gnu99 core.c -o core && ./core 4 You can see that all 4 threads are running on 4 different cores well probably the are swapped from core to core at a time but all 4 cores are working overtime.
core.c: In function ‘main’:
core.c:75:50: warning: cast to pointer from integer of different size [-Wint-to-pointer- cast]
Starting 4 threads
Process 0 says Hello World
Process 1 says Hello World
Process 3 says Hello World
Process 2 says Hello World
I verified it with htop hope it helps.. :) I run dedicated Debian SID x86_64 with 4cores in case you're wondering.

Resources