1

Here is Minimal example :-

#include <stdio.h>
#include <Windows.h>

using namespace std;

void myFunc(TCHAR Path)
{
    printf("pathLen : %lu\n", sizeof(Path));
    printf("character size : %lu\n", sizeof(*Path));
    printf("pathLenInBytes : %lu\n", sizeof(Path) * sizeof(*Path));
}

int main()
{
    TCHAR selfPath[MAX_PATH];

    if (GetModuleFileName(NULL, selfPath, MAX_PATH) == 0)       // Getting exe File Location
        printf("Error : %lu\n", GetLastError());

    printf("Self Path : %s\n", selfPath);
    myFunc(selfPath);

    return 0;
}

Here is Error Output from MinGW-W64 Compiler :-

g++ -Os -s -o goga.exe tesst.cpp
tesst.cpp: In function 'void myFunc(LPCSTR, TCHAR)':
tesst.cpp:9:43: error: invalid type argument of unary '*' (have 'TCHAR' {aka 'char'})
    9 |  printf("character size : %lu\n", sizeof(*Path));
      |                                           ^~~~
tesst.cpp:10:35: error: 'pathLen' was not declared in this scope
   10 |  printf("pathLenInBytes : %lu\n", pathLen * sizeof(*Path));
      |                                   ^~~~~~~
tesst.cpp:10:53: error: invalid type argument of unary '*' (have 'TCHAR' {aka 'char'})
   10 |  printf("pathLenInBytes : %lu\n", pathLen * sizeof(*Path));
      |                                                     ^~~~
tesst.cpp: In function 'int main()':
tesst.cpp:23:22: error: invalid conversion from 'TCHAR*' {aka 'char*'} to 'TCHAR' {aka 'char'} [-fpermissive]
   23 |  myFunc("AppBroker", selfPath);
      |                      ^~~~~~~~
      |                      |
      |                      TCHAR* {aka char*}
tesst.cpp:6:32: note:   initializing argument 2 of 'void myFunc(LPCSTR, TCHAR)'
    6 | void myFunc(LPCSTR Name, TCHAR Path)
      |                          ~~~~~~^~~~

But If I put the GetModuleFineName() directy inside myFunc() then it works :-

#include <stdio.h>
#include <Windows.h>

using namespace std;

void myFunc()
{
    TCHAR selfPath[MAX_PATH];

    if (GetModuleFileName(NULL, selfPath, MAX_PATH) == 0)       // Getting exe File Location
        printf("Error : %lu\n", GetLastError());

    printf("Self Path : %s\n", selfPath);
    printf("pathLen : %lu\n", sizeof(selfPath));
    printf("character size : %lu\n", sizeof(*selfPath));
    printf("pathLenInBytes : %lu\n", sizeof(selfPath) * sizeof(*selfPath));
}

int main()
{
    myFunc();
    return 0;
}

But I dont need it this way. How can i solve this error ?


EDIT : Tried replacing myFunc(TCHAR Path) with myFunc(TCHAR *Path) & also with myFunc(TCHAR Path[]). Both Work and program compiles successfully but the output is different that expected output now !

Expected Output :-

Self Path : C:\Users\username\Desktop\Coding\PETS\muse\goga.exe
pathLen : 260
character size : 1
pathLenInBytes : 260

Output that I Get:-

Self Path : C:\Users\username\Desktop\Coding\PETS\muse\goga.exe
pathLen : 8
character size : 1
pathLenInBytes : 8
0xB00B
  • 1,598
  • 8
  • 26
  • 2
    There's no shortcut to learn programming and programming languages. You need to study hard, not just be told "do this and do that". Please invest in [some good books](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list), and perhaps even take some classes. – Some programmer dude Mar 31 '21 at 10:29
  • 2
    Also please be careful with terms like "C/C++". There is no such language as "C/C++", only the two *very* different languages C and C++. – Some programmer dude Mar 31 '21 at 10:30
  • 1
    The shown code is *not* valid C. You use a C++-only statement. And even if you remove it, the code is still not valid as you have mismatching `printf` format specifiers and argument types, leading to undefined behavior. And please decide, are you programming C or C++? You can't be doing both. Either go all-in C++ or all-in C, please don't try to mix. – Some programmer dude Mar 31 '21 at 10:35
  • Also, the last code block you provided doesn't work, `selfPath` is not defined in `main()`. – ssbssa Mar 31 '21 at 10:36
  • 1
    And please try to think a little... In the `main` function you have the variable `path` which is an *array* of `TCHAR` values. The argument to the `myFunc` function is a single `TCHAR` value, it's not an array. How do the tutorials or books you use tell you how to pass an array as an argument to a function? What do your tutorials or books tell about *array to pointer decay*? What do they say about declaring a pointer variable? – Some programmer dude Mar 31 '21 at 10:37
  • @Some programmer dude "Either go all-in C++ or all-in C", I can't because Windows.h is a C library and stdio.h is also c library (i prefer stdio.h over because of much much smaller exe size) but then i am aso using which is C++ – 0xB00B Mar 31 '21 at 10:53
  • @Some programmer dude Oh ill try that – 0xB00B Mar 31 '21 at 11:29
  • 1
    Why are you using TCHAR? That's for if you need compatibility with Windows 98. Which you don't. Use wchar_t instead. – David Heffernan Mar 31 '21 at 12:29
  • @David Heffernan well, I didn't knew that. I am using TCHAR just because `GetModuleFileName()` returns a TCHAR according to Visual Studio – 0xB00B Mar 31 '21 at 13:24
  • According to Google : TCHAR is a macro that expands to char in ANSI builds (i.e. _UNICODE is not defined) and wchar_t in Unicode builds. Hence TCHAR is recommended instead of wchar_t so that you can compile both ansi as well as unicode version of app. – 0xB00B Mar 31 '21 at 13:26
  • 1
    Nö one uses ANSI encoding, anywhere. Windows uses UTF-16 internally everywhere, in every supported version of the OS. ANSI was great back when Win95 was new. Today there is no single justifiable use case for ANSI encoding. Just use `wchar_t` and forget that you ever heard about the genetic-text mappings. – IInspectable Mar 31 '21 at 13:39
  • 1
    Does this answer your question? [Why is sizeof(array) different in these two cases?](https://stackoverflow.com/questions/7520625/why-is-sizeofarray-different-in-these-two-cases) – Raymond Chen Mar 31 '21 at 13:41
  • @Raymond Chen no, but this one does answers the question (sort of) : https://stackoverflow.com/a/8593393/14976549 – 0xB00B Mar 31 '21 at 14:07
  • Please stop editing an answer into the question. If you want to answer the question, add an answer. – IInspectable Mar 31 '21 at 16:51
  • Please take the [tour], since you forgot to do so. It explains how Stack Overflow works. And why answers need to be submitted as answers. – IInspectable Apr 01 '21 at 12:22

1 Answers1

0

I make an attempt to answer

In your first version, your prototype must be myFunc(TCHAR *Path) or myFunc(TCHAR Path[]) because a path is an array of TCHAR, thus a TCHAR* (a starting documentation can be found here or here)

What you obtained from the first code that compiles is only what you have asked. Let us see:

    printf("pathLen : %lu\n", sizeof(Path));
    printf("character size : %lu\n", sizeof(*Path));
    printf("pathLenInBytes : %lu\n", sizeof(Path) * sizeof(*Path));

First remark: you should not use sizeof (thanks @ Remy LEABEAU for review) with TCHAR* but _tcslen() or lstrlen

  • In the first line, you asked to display the size of path which is a pointer (a TCHAR*). The size of a pointer can be 4 bytes or 8 bytes depending on your system(ref). So 8 is correct.

  • In an array, its name is also the adress of the first element in it. Thus if you try to printf sizeof(*Path), you ask to print the size of the first character pointed by the pointer, thus 1.

  • The two previous lines also explain what the thrid line gives you: 1*8 = 8.

If pathLenis the size in byte of the path, you may use _tcslen() or lstrlen() to compute the length of the path and then use sizeof(TCHAR) as found here

Proposition to obtain what your needed output:

    printf("pathLen : %lu\n", _tcslen(Path));
    printf("TCHAR size : %lu\n", sizeof(TCHAR));
    printf("pathLenInBytes : %lu\n", _tcslen(Path)* sizeof(*Path));
Pat. ANDRIA
  • 2,330
  • 1
  • 13
  • 27
  • That attempt failed. It completely misrepresents the `TCHAR` type alias. – IInspectable Mar 31 '21 at 15:16
  • 1
    Note that when `TCHAR` maps to `wchar_t` (which you should be doing in modern code), `strlen(Path)` will not compile, since it expects a `char*` instead of a `wchar_t*`. When dealing with `TCHAR` strings, use `_tcslen(Path)` or `lstrlen(Path)` instead. Also, for calculating the `pathLen`, multiplying the length by `sizeof(char*)` is jusst plain wrong, get rid of the `sizeof()` altogether and just use `_tcslen()`/`lstrlen()` by itself. And for calculating `pathLenInBytes`, you need to multiply by `sizeof(*Path)` instead of `sizeof(char*)`. – Remy Lebeau Mar 31 '21 at 18:02
  • Thanks @Remy for your comment. I will edit the answer toward your comment. – Pat. ANDRIA Mar 31 '21 at 18:15