Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

FILE structure internals issue building blead on Windows with Visual Studio 2015 RC

1,493 views
Skip to first unread message

A. Sinan Unur

unread,
May 2, 2015, 9:00:03 PM5/2/15
to perl5-...@perl.org
I have been trying to build blead with Visual Studio 2015 RC. I have
been able to deal with a few minor issues, but I hit one where I am
not sure about the right way to proceed. I haven't opened an issue on
RT yet ... This message is an attempt to collect some information so
as to be able to compose a useful report.

The build stops fails with the following errors:

..\perlio.c(3206): error C2039: '_file': is not a member of '_iobuf'
C:\Program Files (x86)\Windows
Kits\10\include\10.0.10056.0\ucrt\corecrt_wstdio.h(26): note: see
declaration of '_iobuf'
..\perlio.c(3394): error C2039: '_ptr': is not a member of '_iobuf'
C:\Program Files (x86)\Windows
Kits\10\include\10.0.10056.0\ucrt\corecrt_wstdio.h(26): note: see
declaration of '_iobuf'
..\perlio.c(3402): error C2039: '_ptr': is not a member of '_iobuf'
C:\Program Files (x86)\Windows
Kits\10\include\10.0.10056.0\ucrt\corecrt_wstdio.h(26): note: see
declaration of '_iobuf'
..\perlio.c(3525): error C2039: '_base': is not a member of '_iobuf'
C:\Program Files (x86)\Windows
Kits\10\include\10.0.10056.0\ucrt\corecrt_wstdio.h(26): note: see
declaration of '_iobuf'
..\perlio.c(3525): warning C4033: 'PerlIOStdio_get_base' must return a value
..\perlio.c(3532): error C2039: '_cnt': is not a member of '_iobuf'
C:\Program Files (x86)\Windows
Kits\10\include\10.0.10056.0\ucrt\corecrt_wstdio.h(26): note: see
declaration of '_iobuf'
..\perlio.c(3532): error C2039: '_ptr': is not a member of '_iobuf'
C:\Program Files (x86)\Windows
Kits\10\include\10.0.10056.0\ucrt\corecrt_wstdio.h(26): note: see
declaration of '_iobuf'
..\perlio.c(3532): error C2039: '_base': is not a member of '_iobuf'
C:\Program Files (x86)\Windows
Kits\10\include\10.0.10056.0\ucrt\corecrt_wstdio.h(26): note: see
declaration of '_iobuf'
..\perlio.c(3532): warning C4033: 'PerlIOStdio_get_bufsiz' must return a value
..\perlio.c(3541): error C2039: '_ptr': is not a member of '_iobuf'
C:\Program Files (x86)\Windows
Kits\10\include\10.0.10056.0\ucrt\corecrt_wstdio.h(26): note: see
declaration of '_iobuf'
..\perlio.c(3541): warning C4033: 'PerlIOStdio_get_ptr' must return a value
..\perlio.c(3548): error C2039: '_cnt': is not a member of '_iobuf'
C:\Program Files (x86)\Windows
Kits\10\include\10.0.10056.0\ucrt\corecrt_wstdio.h(26): note: see
declaration of '_iobuf'
..\perlio.c(3548): warning C4033: 'PerlIOStdio_get_cnt' must return a value
..\perlio.c(3569): error C2039: '_ptr': is not a member of '_iobuf'
C:\Program Files (x86)\Windows
Kits\10\include\10.0.10056.0\ucrt\corecrt_wstdio.h(26): note: see
declaration of '_iobuf'
..\perlio.c(3588): error C2039: '_cnt': is not a member of '_iobuf'
C:\Program Files (x86)\Windows
Kits\10\include\10.0.10056.0\ucrt\corecrt_wstdio.h(26): note: see
declaration of '_iobuf'

The relevant bit from corecrt_wstdio.h:

#ifndef _FILE_DEFINED
#define _FILE_DEFINED
typedef struct _iobuf
{
void* _Placeholder;
} FILE;
#endif

It is no surprise the macros fail.

From here, I do not know where to go.

I should point out that the build proceeds with no problems with VS2013 tools.

Any guidance would be much appreciated. Thank you,

-- Sinan

A. Sinan Unur

unread,
May 4, 2015, 7:45:02 AM5/4/15
to bulk 88, A. Sinan Unur, perl5-...@perl.org
On Sun, May 3, 2015 at 10:10 PM, bulk 88 <bul...@hotmail.com> wrote:
>
> ----------------------------------------
>> Date: Sat, 2 May 2015 20:54:19 -0400
>> Subject: FILE structure internals issue building blead on Windows with Visual Studio 2015 RC
>> From: na...@cpan.org
>> To: perl5-...@perl.org
>>
>> I have been trying to build blead with Visual Studio 2015 RC. I have
>> been able to deal with a few minor issues, but I hit one where I am
>> not sure about the right way to proceed. I haven't opened an issue on
>> RT yet ... This message is an attempt to collect some information so
>> as to be able to compose a useful report.
>>
>> The build stops fails with the following errors:
>>
>> ..\perlio.c(3206): error C2039: '_file': is not a member of '_iobuf'
>> C:\Program Files (x86)\Windows
>> Kits\10\include\10.0.10056.0\ucrt\corecrt_wstdio.h(26): note: see
>> declaration of '_iobuf'

<snip>

> please supply the perlio.i as in "nmake perlio.i"

Unfortunately, `nmake perlio.i` results in:

NMAKE : fatal error U1073: don't know how to make 'perlio.i'
Stop.

Assuming you want the pre-processed output from perlio.c, I ran:

D:\Src\perl\win32> cl -P -nologo -GF -W3 -I..\lib\CORE -I.\include -I.
-I.. -DWIN32 -D_CONSOLE -DNO_STRICT -DWIN64 -DCONSERVATIVE
-D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -DPERLDLL
-DPERL_CORE -O1 -Os -MT -Zi -DNDEBUG -GL -fp:precise -favor:INTEL64
-DPERL_EXTERNAL_GLOB -DPERL_IS_MINIPERL ..\perlio.c

which is based on the compilation command used by the make file.

The output file was about 2MB, about 180K compressed, so I decided
against attaching it. You can download it from:

http://www.nu42.com/tmp/perlio.i.bz2

If you'd rather I email to you privately, please let me know.

Thank you,

-- Sinan

bulk88

unread,
May 4, 2015, 11:30:01 AM5/4/15
to A. Sinan Unur, perl5-...@perl.org
A. Sinan Unur wrote:
> On Sun, May 3, 2015 at 10:10 PM, bulk 88 <bul...@hotmail.com> wrote:
>> ----------------------------------------
>>> Date: Sat, 2 May 2015 20:54:19 -0400
>>> Subject: FILE structure internals issue building blead on Windows with Visual Studio 2015 RC
>>> From: na...@cpan.org
>>> To: perl5-...@perl.org
>>>
>>> I have been trying to build blead with Visual Studio 2015 RC. I have
>>> been able to deal with a few minor issues, but I hit one where I am
>>> not sure about the right way to proceed. I haven't opened an issue on
>>> RT yet ... This message is an attempt to collect some information so
>>> as to be able to compose a useful report.
>>>
>>> The build stops fails with the following errors:
>>>
>>> ..\perlio.c(3206): error C2039: '_file': is not a member of '_iobuf'
>>> C:\Program Files (x86)\Windows
>>> Kits\10\include\10.0.10056.0\ucrt\corecrt_wstdio.h(26): note: see
>>> declaration of '_iobuf'
>
> <snip>
>
>> please supply the perlio.i as in "nmake perlio.i"
>
> Unfortunately, `nmake perlio.i` results in:
>
> NMAKE : fatal error U1073: don't know how to make 'perlio.i'
> Stop.
>


egh, "nmake ../perlio.i" would generate it. I should have remembered that.

> Assuming you want the pre-processed output from perlio.c, I ran:
>
> D:\Src\perl\win32> cl -P -nologo -GF -W3 -I..\lib\CORE -I.\include -I.
> -I.. -DWIN32 -D_CONSOLE -DNO_STRICT -DWIN64 -DCONSERVATIVE
> -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -DPERLDLL
> -DPERL_CORE -O1 -Os -MT -Zi -DNDEBUG -GL -fp:precise -favor:INTEL64
> -DPERL_EXTERNAL_GLOB -DPERL_IS_MINIPERL ..\perlio.c
>
> which is based on the compilation command used by the make file.
>
> The output file was about 2MB, about 180K compressed, so I decided
> against attaching it. You can download it from:
>
> http://www.nu42.com/tmp/perlio.i.bz2
>
> If you'd rather I email to you privately, please let me know.
>
> Thank you,
>
> -- Sinan

I dont see your perlio.c problem with my VC 2015 RC compiler. I do see a
whole pile of other problems.

First problem, MS split "msvcrt.lib" into 3 different files per
http://blogs.msdn.com/b/vcblog/archive/2015/03/03/introducing-the-universal-crt.aspx
. That shows itself as being impossible to link anything

C:\p521\src\win32>nmake test

Microsoft (R) Program Maintenance Utility Version 14.00.22816.0
Copyright (C) Microsoft Corporation. All rights reserved.

link -subsystem:console -out:..\generate_uudmap.exe -nologo
-nodefaultlib -debug -opt:ref,icf -ltcg -libpath:"c:\p521\lib\CORE"
-machine:x86 "/manifestdependency:type='Win32'
name='Microsoft.Windows.Common-Controls' version='6.0.0.0'
processorArchitecture='*' publicKeyToken='6595b64144ccf1df'
language='*'" oldnames.lib kernel32.lib user32.lib gdi32.lib
winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib
oleaut32.lib netapi32.lib uuid.lib ws2_32.lib mpr.lib winmm.lib
version.lib odbc32.lib odbccp32.lib comctl32.lib msvcrt.lib
..\generate_uudmap.obj
generate_uudmap.obj : error LNK2001: unresolved external symbol
__imp__strerror
generate_uudmap.obj : error LNK2001: unresolved external symbol __imp__fopen
generate_uudmap.obj : error LNK2001: unresolved external symbol
__imp____stdio_c
ommon_vfprintf
generate_uudmap.obj : error LNK2001: unresolved external symbol __imp__exit
generate_uudmap.obj : error LNK2001: unresolved external symbol __imp__fputs
generate_uudmap.obj : error LNK2001: unresolved external symbol
__imp___errno
generate_uudmap.obj : error LNK2001: unresolved external symbol
__imp__fclose
generate_uudmap.obj : error LNK2001: unresolved external symbol __imp__fputc
generate_uudmap.obj : error LNK2001: unresolved external symbol
__imp____acrt_iob_func
msvcrt.lib(exe_main.obj) : error LNK2001: unresolved external symbol
__seh_filter_exe
msvcrt.lib(exe_main.obj) : error LNK2001: unresolved external symbol
__set_app_type
msvcrt.lib(exe_main.obj) : error LNK2001: unresolved external symbol
___setusermatherr
msvcrt.lib(exe_main.obj) : error LNK2001: unresolved external symbol
__configure_narrow_argv
msvcrt.lib(exe_main.obj) : error LNK2001: unresolved external symbol
__initialize_narrow_environment
msvcrt.lib(utility.obj) : error LNK2001: unresolved external symbol
__initialize_narrow_environment
msvcrt.lib(exe_main.obj) : error LNK2001: unresolved external symbol
__get_initial_narrow_environment
msvcrt.lib(exe_main.obj) : error LNK2001: unresolved external symbol
__initterm
msvcrt.lib(exe_main.obj) : error LNK2001: unresolved external symbol
__initterm_e
msvcrt.lib(exe_main.obj) : error LNK2001: unresolved external symbol _exit
msvcrt.lib(exe_main.obj) : error LNK2001: unresolved external symbol __exit
msvcrt.lib(exe_main.obj) : error LNK2001: unresolved external symbol
__set_fmode

msvcrt.lib(exe_main.obj) : error LNK2001: unresolved external symbol
___p___argc

msvcrt.lib(exe_main.obj) : error LNK2001: unresolved external symbol
___p___argv

msvcrt.lib(exe_main.obj) : error LNK2001: unresolved external symbol __cexit
msvcrt.lib(utility.obj) : error LNK2001: unresolved external symbol __cexit
msvcrt.lib(exe_main.obj) : error LNK2001: unresolved external symbol
__c_exit
msvcrt.lib(exe_main.obj) : error LNK2001: unresolved external symbol
__register_thread_local_exe_atexit_callback
msvcrt.lib(exe_main.obj) : error LNK2001: unresolved external symbol
___telemetry_main_invoke_trigger
msvcrt.lib(exe_main.obj) : error LNK2001: unresolved external symbol
___telemetry_main_return_trigger
msvcrt.lib(exe_main.obj) : error LNK2001: unresolved external symbol
__configthreadlocale
msvcrt.lib(exe_main.obj) : error LNK2001: unresolved external symbol
__set_new_mode
msvcrt.lib(exe_main.obj) : error LNK2001: unresolved external symbol
___p__commode
msvcrt.lib(utility.obj) : error LNK2001: unresolved external symbol
__seh_filter_dll
msvcrt.lib(utility.obj) : error LNK2001: unresolved external symbol
__initialize_onexit_table
msvcrt.lib(utility.obj) : error LNK2001: unresolved external symbol
__register_onexit_function
msvcrt.lib(utility.obj) : error LNK2001: unresolved external symbol
__execute_onexit_table
msvcrt.lib(utility.obj) : error LNK2001: unresolved external symbol
__crt_atexit
msvcrt.lib(utility.obj) : error LNK2001: unresolved external symbol
__crt_at_quick_exit
msvcrt.lib(tncleanup.obj) : error LNK2001: unresolved external symbol
___std_type_info_destroy_list
msvcrt.lib(default_precision.obj) : error LNK2001: unresolved external
symbol __controlfp_s
msvcrt.lib(utility_desktop.obj) : error LNK2001: unresolved external
symbol _terminate
msvcrt.lib(utility_desktop.obj) : error LNK2001: unresolved external
symbol _memset
msvcrt.lib(_chandler4gs_.obj) : error LNK2001: unresolved external
symbol __except_handler4_common
..\generate_uudmap.exe : fatal error LNK1120: 41 unresolved externals
NMAKE : fatal error U1077: '"C:\Program Files\Microsoft Visual Studio
14.0\VC\BI
N\link.EXE"' : return code '0x460'
Stop.

C:\p521\src\win32>


After hacking the nmake makefile with "LIBC = msvcrt.lib vcruntime.lib
ucrt.lib" I can't compile sv.c.

C:\p521\src\win32>nmake mini/sv.obj

Microsoft (R) Program Maintenance Utility Version 14.00.22816.0
Copyright (C) Microsoft Corporation. All rights reserved.

cl -c -nologo -GF -W3 -I..\lib\CORE -I.\include -I. -I..
-DWIN32 -D_CONS
OLE -DNO_STRICT -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE
-DPERLDLL
-DPERL_CORE -O1 -MD -Zi -DNDEBUG -GS- -DPERL_EXTERNAL_GLOB
-DPERL_IS_MINIPERL
-Fo.\mini\sv.obj ..\sv.c
sv.c
C:\Program Files\Microsoft Visual Studio 14.0\VC\INCLUDE\stdbool.h(15):
warning
C4005: 'bool': macro redefinition
c:\p521\src\handy.h(103): note: see previous definition of 'bool'
..\sv.c(989): error C2099: initializer is not a constant
NMAKE : fatal error U1077: '"C:\Program Files\Microsoft Visual Studio
14.0\VC\BI
N\cl.EXE"' : return code '0x2'
Stop.

C:\p521\src\win32>


The line number above doesn't match blead, but it is the last line of
"static const struct body_details bodies_by_type[]" array.

Deleting the elements of that array one by one, shows that atleast this
initializer is causing the "not a constant" error. I am not sure if the
later SV type slices are also causing "not a constant" but I can't
compile sv.c until I cut back to SVt_PV.


{ sizeof(XPV) - STRUCT_OFFSET(XPV, xpv_cur),
copy_length(XPV, xpv_len) - STRUCT_OFFSET(XPV, xpv_cur),
+ STRUCT_OFFSET(XPV, xpv_cur),
SVt_PV, FALSE, NONV, HASARENA,
FIT_ARENA(0, sizeof(XPV) - STRUCT_OFFSET(XPV, xpv_cur)) },

a .i output shows

-------------------------------------------------------------------
static const struct body_details bodies_by_type[] = {

{ 0, 0, 0, SVt_NULL, (0), (1), (0), 0 },


{ 0,
sizeof(IV),
(size_t)(&(((XPVIV *)0)->xiv_u.xivu_iv)), SVt_IV, (0), (1),
(0) , 0
},





#line 976 "../sv.c"
{ sizeof(NV), sizeof(NV),
(size_t)(&(((XPVNV *)0)->xnv_u)),
SVt_NV, (0), (0), (1), (U32)(0 ? ( 0 * sizeof(NV) <= 4080) ? 0 *
sizeof(NV) : ((size_t)(4080 / sizeof(NV)) * sizeof(NV)) : ((size_t)(4080
/ sizeof(NV)) * sizeof(NV))) },
#line 980 "../sv.c"

{ sizeof(XPV) - (size_t)(&(((XPV *)0)->xpv_cur)),
(size_t)(&(((XPV *)0)->xpv_len_u.xpvlenu_len)) + sizeof
(((XPV*)((const SV *)0)->sv_any)->xpv_len_u.xpvlenu_len) -
(size_t)(&(((XPV *)0)->xpv_cur)),
+ (size_t)(&(((XPV *)0)->xpv_cur)),
SVt_PV, (0), (1), (1),
(U32)(0 ? ( 0 * sizeof(XPV) - (size_t)(&(((XPV *)0)->xpv_cur)) <=
4080) ? 0 * sizeof(XPV) - (size_t)(&(((XPV *)0)->xpv_cur)) :
((size_t)(4080 / sizeof(XPV) - (size_t)(&(((XPV *)0)->xpv_cur))) *
sizeof(XPV) - (size_t)(&(((XPV *)0)->xpv_cur))) : ((size_t)(4080 /
sizeof(XPV) - (size_t)(&(((XPV *)0)->xpv_cur))) * sizeof(XPV) -
(size_t)(&(((XPV *)0)->xpv_cur)))) },



};
-------------------------------------------------------------------

I dont have time to file bug tickets with MS about this.


The CC I am using is
-------------------------------------------------------------------
C:\p521\src\win32>cl
Microsoft (R) C/C++ Optimizing Compiler Version 19.00.22816 for x86
Copyright (C) Microsoft Corporation. All rights reserved.

usage: cl [ option... ] filename... [ /link linkoption... ]

C:\p521\src\win32>
-------------------------------------------------------------------

A. Sinan Unur

unread,
May 4, 2015, 11:45:04 AM5/4/15
to bulk88, A. Sinan Unur, perl5-...@perl.org
Yes, I have already been working through the other problems.

I actually solved the linking issue by removing the `-nodefaultlib` option.

As for the problem in sv.c, removing the leading + sign from a certain
field fixes the issue. I do not know if the + sign is needed for other
environments. For example:

diff --git a/sv.c b/sv.c
index 2bb0346..ab8a74c 100644
--- a/sv.c
+++ b/sv.c
@@ -980,25 +980,24 @@ static const struct body_details bodies_by_type[] = {

{ sizeof(XPV) - STRUCT_OFFSET(XPV, xpv_cur),
copy_length(XPV, xpv_len) - STRUCT_OFFSET(XPV, xpv_cur),
- + STRUCT_OFFSET(XPV, xpv_cur),
+ STRUCT_OFFSET(XPV, xpv_cur),
SVt_PV, FALSE, NONV, HASARENA,
FIT_ARENA(0, sizeof(XPV) - STRUCT_OFFSET(XPV, xpv_cur)) },

etc etc.

I have been trying to complete a build, and I was going address each
of these separately once I got to that point. I think the make file
and config_H.vc need some updating, but I am in the process of working
through all of that.

With the _iobuf problem, I did not even know how to make any progress
from that point. Anything I should try to look at, dig into?

Thanks,

-- Sinan

bulk88

unread,
May 4, 2015, 2:15:02 PM5/4/15
to A. Sinan Unur, perl5-...@perl.org
A. Sinan Unur wrote:
> Yes, I have already been working through the other problems.
>
> I actually solved the linking issue by removing the `-nodefaultlib` option.
>
> As for the problem in sv.c, removing the leading + sign from a certain
> field fixes the issue. I do not know if the + sign is needed for other
> environments.

IDK either, its from nclark commit
http://perl5.git.perl.org/perl.git/commitdiff/889d28b2ea2c17517fae97cf4a92bd3563aaa74f
"Reinstate space optimisations to SV body structures."

> For example:
>
> diff --git a/sv.c b/sv.c
> index 2bb0346..ab8a74c 100644
> --- a/sv.c
> +++ b/sv.c
> @@ -980,25 +980,24 @@ static const struct body_details bodies_by_type[] = {
>
> { sizeof(XPV) - STRUCT_OFFSET(XPV, xpv_cur),
> copy_length(XPV, xpv_len) - STRUCT_OFFSET(XPV, xpv_cur),
> - + STRUCT_OFFSET(XPV, xpv_cur),
> + STRUCT_OFFSET(XPV, xpv_cur),
> SVt_PV, FALSE, NONV, HASARENA,
> FIT_ARENA(0, sizeof(XPV) - STRUCT_OFFSET(XPV, xpv_cur)) },
>
> etc etc.
>

That is clearly a compiler bug, since it isn't broken on VC 2013. And VC
2015 is still a beta product which could get bug fixes potentially. It
would service alot more people to get it fixed by MS before VC 2015 gold
is shipped.

> I have been trying to complete a build, and I was going address each
> of these separately once I got to that point. I think the make file
> and config_H.vc need some updating, but I am in the process of working
> through all of that.
>
> With the _iobuf problem, I did not even know how to make any progress
> from that point. Anything I should try to look at, dig into?
>
> Thanks,
>
> -- Sinan


Is there any particular reason you are trying VC 2015 beta? I highly
doubt P5P will add a new "platform" (VC version) during the code freeze
(anyone else want to speak up?). Maybe for 5.22.1 VC 2015 support can be
added but that is months away.


The FILE struct issue I will address later today. I am researching what
MS changed for VC 2015 specifically and if its ISO C compliant.

A. Sinan Unur

unread,
May 4, 2015, 9:00:02 PM5/4/15
to bulk88, A. Sinan Unur, perl5-...@perl.org
On Mon, May 4, 2015 at 2:10 PM, bulk88 <bul...@hotmail.com> wrote:
> A. Sinan Unur wrote:
...
>> As for the problem in sv.c, removing the leading + sign from a certain
>> field fixes the issue. I do not know if the + sign is needed for other
>> environments.

...

> That is clearly a compiler bug, since it isn't broken on VC 2013.

It looks like that to me too, but, again, I wanted to get to a
building successfully, and then re-trace and issue each issue I
encountered along the way.

> Is there any particular reason you are trying VC 2015 beta? I highly doubt
> P5P will add a new "platform" (VC version) during the code freeze (anyone
> else want to speak up?). Maybe for 5.22.1 VC 2015 support can be added but
> that is months away.

I didn't think it would make it to 5.22, but when the release
candidate came out, I wanted to see how far I could get.

Thanks for your help,

-- Sinan

bulk88

unread,
May 5, 2015, 6:30:01 AM5/5/15
to A. Sinan Unur, perl5-...@perl.org
bulk88 wrote:
> The FILE struct issue I will address later today. I am researching what
> MS changed for VC 2015 specifically and if its ISO C compliant.

vc 2013
_______________________________________________________________________
/***
*stdio.h - definitions/declarations for standard I/O routines
*
* Copyright (c) Microsoft Corporation. All rights reserved.
*
*Purpose:
* This file defines the structures, values, macros, and functions
* used by the level 2 I/O ("standard I/O") routines.
* [ANSI/System V]
*
* [Public]
*
****/

#pragma once

#ifndef _INC_STDIO
#define _INC_STDIO

#include <crtdefs.h>

/*
* Currently, all MS C compilers for Win32 platforms default to 8 byte
* alignment.
*/
#pragma pack(push,_CRT_PACKING)

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */


/* Buffered I/O macros */

#define BUFSIZ 512

#ifdef _CRTBLD
/*
* Real default size for stdio buffers
*/
#define _INTERNAL_BUFSIZ 4096
#define _SMALL_BUFSIZ 512
#endif /* _CRTBLD */

/*
* Default number of supported streams. _NFILE is confusing and
obsolete, but
* supported anyway for backwards compatibility.
*/
#define _NFILE _NSTREAM_

#define _NSTREAM_ 512

/*
* Number of entries in _iob[] (declared below). Note that _NSTREAM_
must be
* greater than or equal to _IOB_ENTRIES.
*/
#define _IOB_ENTRIES 20

#define EOF (-1)


#ifndef _FILE_DEFINED
struct _iobuf {
char *_ptr;
int _cnt;
char *_base;
int _flag;
int _file;
int _charbuf;
int _bufsiz;
char *_tmpfname;
};
typedef struct _iobuf FILE;
#define _FILE_DEFINED
#endif /* _FILE_DEFINED */


/* Directory where temporary files may be created. */

#define _P_tmpdir "\\"
#define _wP_tmpdir L"\\"

/* L_tmpnam = length of string _P_tmpdir
* + 1 if _P_tmpdir does not end in "/" or "\", else 0
* + 12 (for the filename string)
* + 1 (for the null terminator)
* L_tmpnam_s = length of string _P_tmpdir
* + 1 if _P_tmpdir does not end in "/" or "\", else 0
* + 16 (for the filename string)
* + 1 (for the null terminator)
*/
#define L_tmpnam (sizeof(_P_tmpdir) + 12)
#if __STDC_WANT_SECURE_LIB__
#define L_tmpnam_s (sizeof(_P_tmpdir) + 16)
#endif /* __STDC_WANT_SECURE_LIB__ */



/* Seek method constants */

#define SEEK_CUR 1
#define SEEK_END 2
#define SEEK_SET 0

_______________________________________________________________________


vc 2015
_______________________________________________________________________
//
// corecrt_wstdio.h
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// This file declares the wide character (wchar_t) I/O functionality,
shared by
// <stdio.h> and <wchar.h>. It also defines several core I/O types,
which are
// also shared by those two headers.
//
#pragma once

#include <corecrt.h>
#include <corecrt_stdio_config.h>

_CRT_BEGIN_C_HEADER


//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//
// Stream I/O Declarations Required by this Header
//
//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
#ifndef _FILE_DEFINED
#define _FILE_DEFINED
typedef struct _iobuf
{
void* _Placeholder;
} FILE;
#endif
_______________________________________________________________________

//
// stdio.h
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// The C Standard Library <stdio.h> header.
//
#pragma once
#define _INC_STDIO

#include <corecrt.h>
#include <corecrt_wstdio.h>

_CRT_BEGIN_C_HEADER

/* Buffered I/O macros */

#define BUFSIZ 512



/*
* Default number of supported streams. _NFILE is confusing and
obsolete, but
* supported anyway for backwards compatibility.
*/
#define _NFILE _NSTREAM_

#define _NSTREAM_ 512

/*
* Number of entries in _iob[] (declared below). Note that _NSTREAM_
must be
* greater than or equal to _IOB_ENTRIES.
*/
#define _IOB_ENTRIES 3

#define EOF (-1)

#define _IOFBF 0x0000
#define _IOLBF 0x0040
#define _IONBF 0x0004



#define L_tmpnam 260 // _MAX_PATH
#if __STDC_WANT_SECURE_LIB__
#define L_tmpnam_s L_tmpnam
#endif



/* Seek method constants */

#define SEEK_CUR 1
#define SEEK_END 2
#define SEEK_SET 0
_______________________________________________________________________


as per http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf (C99
spec?) section 7.19.1

_______________________________________________________________________
2 The types declared are size_t (described in 7.17); FILE which is an
object type capable of recording all the information needed to control a
stream, including its file position indicator, a pointer to its
associated buffer (if any), an error indicator that records whether a
read/write error has occurred, and an end-of-file indicator that records
whether the end of the file has been reached;
_______________________________________________________________________

There is no requirement as to the members or their names of a FILE *.

So is Perl at fault for using undocumented libc members, or is MS at
fault for breaking decades of back compat? Here is the first function
that fails to compile

_______________________________________________________________________
static int
PerlIOStdio_invalidate_fileno(pTHX_ FILE *f)
{
PERL_UNUSED_CONTEXT;

/* XXX this could use PerlIO_canset_fileno() and
* PerlIO_set_fileno() support from Configure
*/
# if defined(__UCLIBC__)
/* uClibc must come before glibc because it defines __GLIBC__ as
well. */
f->__filedes = -1;
return 1;
# elif defined(__GLIBC__)
/* There may be a better way for GLIBC:
- libio.h defines a flag to not close() on cleanup
*/
f->_fileno = -1;
return 1;
# elif defined(__sun)
PERL_UNUSED_ARG(f);
return 0;
# elif defined(__hpux)
f->__fileH = 0xff;
f->__fileL = 0xff;
return 1;
/* Next one ->_file seems to be a reasonable fallback, i.e. if
your platform does not have special entry try this one.
[For OSF only have confirmation for Tru64 (alpha)
but assume other OSFs will be similar.]
*/
# elif defined(_AIX) || defined(__osf__) || defined(__irix__)
f->_file = -1;
return 1;
# elif defined(__FreeBSD__)
/* There may be a better way on FreeBSD:
- we could insert a dummy func in the _close function entry
f->_close = (int (*)(void *)) dummy_close;
*/
f->_file = -1;
return 1;
# elif defined(__OpenBSD__)
/* There may be a better way on OpenBSD:
- we could insert a dummy func in the _close function entry
f->_close = (int (*)(void *)) dummy_close;
*/
f->_file = -1;
return 1;
# elif defined(__EMX__)
/* f->_flags &= ~_IOOPEN; */ /* Will leak stream->_buffer */
f->_handle = -1;
return 1;
# elif defined(__CYGWIN__)
/* There may be a better way on CYGWIN:
- we could insert a dummy func in the _close function entry
f->_close = (int (*)(void *)) dummy_close;
*/
f->_file = -1;
return 1;
# elif defined(WIN32)
# if defined(UNDER_CE)
/* WIN_CE does not have access to FILE internals, it hardly has FILE
structure at all
*/
# else
f->_file = -1;
# endif
return 1;
# else
#if 0
/* Sarathy's code did this - we fall back to a dup/dup2 hack
(which isn't thread safe) instead
*/
# error "Don't know how to set FILE.fileno on your platform"
#endif
PERL_UNUSED_ARG(f);
return 0;
# endif
}
_______________________________________________________________________


Some quotes from universal CRT source code.
_______________________________________________________________________
// Ensure that __crt_stdio_stream_data* and FILE* pointers are freely
convertible:
static_assert(
offsetof(__crt_stdio_stream_data, _public_file) == 0,
"FILE member of __crt_stdio_stream_data is not at offset zero."
);

static_assert(
sizeof(FILE) == sizeof(void*),
"FILE structure has unexpected size."
);
_______________________________________________________________________
extern "C" size_t __cdecl _fread_nolock_s(
void* const buffer,
size_t const buffer_size,
size_t const element_size,
size_t const element_count,
FILE* const public_stream
)
{
__crt_stdio_stream const stream(public_stream);

if (element_size == 0 || element_count == 0)
return 0;

_VALIDATE_RETURN(buffer != nullptr, EINVAL, 0);
if (!stream.valid() || element_count > (SIZE_MAX / element_size))
{
_______________________________________________________________________
class __crt_stdio_stream
{
public:

__crt_stdio_stream() throw()
: _stream(nullptr)
{
}

explicit __crt_stdio_stream(FILE* const stream) throw()
: _stream(reinterpret_cast<__crt_stdio_stream_data*>(stream))
{
}
_______________________________________________________________________
//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//
// Internal Stream Types (__crt_stdio_stream and friends)
//
//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
struct __crt_stdio_stream_data
{
union
{
FILE _public_file;
char* _ptr;
};

char* _base;
int _cnt;
long _flags;
long _file;
int _charbuf;
int _bufsiz;
char* _tmpfname;
CRITICAL_SECTION _lock;
};
_______________________________________________________________________

So a FILE * is now a C++ object (probably based on the above if my C++
knowledge is good enough), hence it is opaque. Now what? file a MS bug
report? Or is perl going to require a C++ shim .o file and #include
non-public corecrt_internal_stdio.h to access those members?

A. Sinan Unur

unread,
May 5, 2015, 7:15:02 AM5/5/15
to bulk88, A. Sinan Unur, perl5-...@perl.org
On Tue, May 5, 2015 at 6:17 AM, bulk88 <bul...@hotmail.com> wrote:

> So a FILE * is now a C++ object (probably based on the above if my C++
> knowledge is good enough), hence it is opaque. Now what? file a MS bug
> report? Or is perl going to require a C++ shim .o file and #include
> non-public corecrt_internal_stdio.h to access those members?

Yes, and that is what gave me pause. One could certainly plow ahead,
figuring out the new internal details, trying to hook things up, but
it feels wrong to depend on specific members of the FILE structure.

All C99 has to say (7.19.1) on this is:

"FILE ... is an object type capable of recording all the information
needed to control a stream, including its file position indicator, a
pointer to its associated buffer (if any), an error indicator that
records whether a read/write error has occurred, and an end-of-file
indicator that records whether the end of the file has been reached;"

Is it a bug to replace this with a pointer to something that is
capable of doing those things?

Should perlio really depend on compiler specific implementation details?

There are the answers one would give to these questions if we lived in
an ideal world. And, then there is the world we live in.

The way this issue resolved, or whether it is resolved, may have
implications for Perl on all platforms.

Hence, my inability to figure out how to proceed.

Thank you,

-- Sinan

A. Sinan Unur

unread,
May 5, 2015, 7:45:02 AM5/5/15
to A. Sinan Unur, bulk88, perl5-...@perl.org
On Mon, May 4, 2015 at 8:44 PM, A. Sinan Unur <na...@cpan.org> wrote:
> On Mon, May 4, 2015 at 2:10 PM, bulk88 <bul...@hotmail.com> wrote:
>> A. Sinan Unur wrote:
> ...
>>> As for the problem in sv.c, removing the leading + sign from a certain
>>> field fixes the issue. I do not know if the + sign is needed for other
>>> environments.
...
>> That is clearly a compiler bug, since it isn't broken on VC 2013

I just submitted Microsoft a bug report for this. See:
<https://connect.microsoft.com/VisualStudio/feedback/details/1304939>

If you do have a Microsoft ID, it *might* be useful to vote for it ;-)

--- bug report ---

Consider the following simple C program:

#include <stddef.h>
#include <stdio.h>

struct x {
int y;
char z;
};

static const size_t i = +offsetof(struct x, z);

int main(void) {
printf("MSCVER: %d\n", _MSC_VER);
return 0;
}

Compiling with VS2013CE command line tools:

C:\...\Temp> cl t.c

Microsoft (R) C/C++ Optimizing Compiler Version 18.00.31101 for x64
Copyright (C) Microsoft Corporation. All rights reserved.

t.c

Microsoft (R) Incremental Linker Version 12.00.31101.0
Copyright (C) Microsoft Corporation. All rights reserved.

/out:t.exe
t.obj

C:\...\Temp> t.exe
MSCVER: 1800


Now, try the VS2015RC-CE tools:

C:\...\Temp> cl t.c
Microsoft (R) C/C++ Optimizing Compiler Version 19.00.22816 for x64
Copyright (C) Microsoft Corporation. All rights reserved.

t.c
t.c(9): error C2099: initializer is not a constant

Now, consider a simple change:

static const size_t i = 42+offsetof(struct x, z);

This causes the VS2015RC-CE tools to compile without problems:

C:\...\Temp> cl t.c
Microsoft (R) C/C++ Optimizing Compiler Version 19.00.22816 for x64
Copyright (C) Microsoft Corporation. All rights reserved.

t.c
Microsoft (R) Incremental Linker Version 14.00.22816.0
Copyright (C) Microsoft Corporation. All rights reserved.

/out:t.exe
t.obj

C:\...\Temp> t.exe
MSCVER: 1900

Clearly,

+offsetof(struct x, z);

is equivalent to 0+offsetof(struct x, z), and, as such is just as
constant an expression as 42+offsetof(struct x, z) and should compile
as such.

I encountered this bug while trying to build Perl using VS2015RC
tools. It prevents sv.c from compiling.

Thank you for making the Community Editions of Visual Studio tools
available, and thank you for your consideration of this bug report.

-- A. Sinan Unur

Tony Cook

unread,
May 6, 2015, 2:15:03 AM5/6/15
to A. Sinan Unur, bulk88, perl5-...@perl.org
Please try the tonyc/vc2015-file branch.

On a POSIXish[1] system Configure detects whether FILE has the right
pointers, on Win32 we use canned configs, which reflect the pre-VC2015
C runtime.

Assuming it helps, for a full fix this will probably become something
controlled by CCTYPE, with the canned config.vc setting both
d_stdstdio and d_stdiobase to undef so miniperl will build.

Tony

[1] eg. Haiku is POSIXish enough

Leon Timmermans

unread,
May 6, 2015, 3:30:03 AM5/6/15
to bulk88, A. Sinan Unur, perl5-...@perl.org
On Tue, May 5, 2015 at 12:17 PM, bulk88 <bul...@hotmail.com> wrote:
So a FILE * is now a C++ object (probably based on the above if my C++ knowledge is good enough), hence it is opaque. Now what? file a MS bug report? Or is perl going to require a C++ shim .o file and #include non-public corecrt_internal_stdio.h to access those members?

This sort of thing happened on the UNIX side before, I don't think they're breaking anything that ought not to be broken, we are just being naughty. It does mean :stdio's readline becomes unbearably slow.

Leon

0 new messages